← ST-Computer 03 / 1987

Elemente der kĂŒnstlichen Intelligenz (1): Atome und Listen

Kurs

Der Autor

Dr. Karl Sarnow

wird Sie mit dieser Serie in die Welt der kĂŒnstlichen Intelligenz einfĂŒhren.

Er studierte Physik an der TU Hannover und unterrichtet zur Zeit an einem Gymnasium die FĂ€cher Mathematik, Physik und Informatik.

Anfang 1986 stieg er auf den ST um und kommuniziert mit ihm in allen nur erdenklichen Sprachen. Seine bevorzugten Programmiersprachen sind C, LISP und Prolog.

Zum Geleit

Dieser Artikel ist der erste in einer Reihe von AufsĂ€tzen, in denen ich Ihnen Probleme und Verfahrensweisen, die im Bereich der kĂŒnstlichen Intelligenz vorliegen, nahebringen möchte. Dabei werde ich mich bemĂŒhen, die beiden aktuellen Sprachen der KI — LISP und PROLOG - in gleicher Weise zu berĂŒcksichtigen. Da beide Sprachen im Public-Domain-Service der ST-Computer-Redaktion vorliegen, sollte es dem Leser nicht schwerfallen, diesem Kurs zu folgen. Übrigens hat jeder ST-Besitzer ja schon von Haus aus die ausgezeichnete Version einer Kl-Sprache mitbekommen: Die (viel zu wenig beachtete Logo-Version von Digital Research, die ich bei dieser Gelegenheit gerne aufwerten möchte. LOGO ist nicht nur die Turtle-Sprache fĂŒr Kinder. Als LISP-Derivat ist LOGO ohne Schwierigkeiten in der Lage, das zu vollbringen, was LISP kann. Deshalb werde ich die entsprechende LOGO-Variante ebenfalls erlĂ€utern. Jeder Kurs ist einem Schwerpunkt gewidmet und behandelt die fĂŒr das entsprechende Thema geeigneten Funktionen (LISP, LOGO) bzw. PrĂ€dikate (PROLOG). FĂŒr eine Übersicht ĂŒber LISP und PROLOG und die allgemeinen Anwendungsgebiete der KI sei auf meine bisher in dieser Zeitschrift erschienenen Artikel verwiesen (Heft Nr. 1/86 und 3/86). NatĂŒrlich wird es sich nicht vermeiden lassen, daß das eine oder andere Thema vorrangig in einer der drei Sprachen behandelt wird und die anderen Sprachen etwas zurĂŒcktreten. Ich möchte jedoch den Überblick ĂŒber die Methoden der KI von der Einengung der jeweils verwendeten Sprache befreien und andererseits die spezifischen Eigenschaften der jeweiligen Sprache erhalten.

Atome und Listen als Datenelemente

Bei Problemen der kĂŒnstlichen Intelligenz tritt die Rechenfertigkeit hinter der FĂ€higkeit der Symbolmanipulation zurĂŒck. Logischerweise bedient man sich hierzu anderer Datenstrukturen als fĂŒr die Bearbeitung arithmetischer Probleme. Die beiden Datentypen, mit denen wir uns hauptsĂ€chlich beschĂ€ftigen, sind Atome und Listen (einzige Ausnahme: Objekte in XLISP, siehe Literaturliste 2. Atome (gr.: atomos, unteilbar) sind Datenelemente, die nicht weiter strukturiert sind und folglich auch nicht in kleinere Bestandteile zerlegt werden können. Dies können symbolische Namen sein (hallo, auto, champagner, hexamethylentetramin, ...) oder Zahlen. Im letzten Fall spricht man von numerischen Atomen.

Listen sind im einfachsten Fall nicht anders als miteinander verbundene Atome. In LISP werden die einzelnen Elemente einer Liste von runden Klammern eingeschlossen, in PROLOG und LOGO von eckigen. Also ist

(hallo auto 3.141)

bzw.

[hallo, auto, 3.141]

eine Liste in LISP, LOGO bzw. PROLOG, welche die Atome hallo, auto und 3.141 enthÀlt. Allerdings können Listen wiederum Listen als Elemente enthalten [(Rekursion, ick hör dir trapsen!)]. Ein etwas sinnvolleres Beispiel wÀre (LISP-Notation):

(rufname (vornamel vorname2 vorname3) name)

Auf die natĂŒrliche Intelligenz des Lesers vertrauend, verzichte ich auf die PROLOG- und LOGO-Schreibweise.

In dieser Liste werden die Patennamen als Unterliste gefĂŒhrt. Die Liste selbst besteht also aus drei Elementen, den Atomen rufname und name sowie der Liste mit den drei Patennamen. LISP schießt in Sachen Listenbehandlung den Vogel ab, weil der Interpreter jeden Befehl in Listenform erwartet.

Die einfachsten Beispiele fĂŒr Listenverarbeitung stammen deshalb in LISP aus dem Bereich der Arithmetik - ein Indiz fĂŒr den Wahrheitsgehalt der Vermutung, daß reine RechenfĂ€higkeit und Intelligenz wenig korreliert sind.

Gibt man in LISP die folgende Liste ein, interpretiert sie der Interpreter als einen auszufĂŒhrenden Befehl und gibt prompt das Ergebnis der AusfĂŒhrung bekannt (fett: Benutzereingabe, kursiv: Antwort des Interpreters).

(+ 1 2) 3

Da XLISP ein eval_LISP ist (siehe Literaturliste 2), erkennt das System beim Versuch, die Liste zu evaluieren, daß das erste Element der Liste ein Atom ist, das die Bedeutung einer im System eingebauten Funktion hat, und fĂŒhrt die Funktionsberechnung durch. Solche im System eingebauten Funktionen tragen die Bezeichnung Primitiv. Am Beispiel der Addition in LISP kann man auch einen Vorteil der Liste gegenĂŒber anderen Datenstrukturen erkennen. So erlaubt LISP mehr als 2 Argumente bei allen arithmetischen Operationen:

(+ 1 2 3 4 5) 15 (★ 2 4 3) 24

Listen in den Kl-Sprachen haben zudem den Vorteil, daß ihre Elemente typenlos sind (im Gegensatz zu PASCAL oder C). Beispielsweise werden die folgenden beiden Listen gleichwertig als EintrĂ€ge einer Gehaltsliste akzeptiert:

(schmidt emil 1200.50) (meier (hans georg gustav) 3179.20)

In allen drei Sprachen werden ĂŒbrigens die Rechenoperationen in PrĂ€fix-Notation angegeben. Nur LOGO als „AnfĂ€ngersprache“ hat hier dem traditionellen Infix-Denken Tribut gezollt und erlaubt zusĂ€tzlich noch die Infix-Notation fĂŒr arithmetische Operationen. Die PrĂ€fix-Notation hat den Vorteil, daß der Operator immer an der gleichen Stelle steht, unabhĂ€ngig von der Anzahl der Argumente der Operation. Das Umdenken ist zwar lĂ€stig, doch wenn die natĂŒrliche Intelligenz beim Umgang mit der kĂŒnstlichen Intelligenz etwas abbekommt, so ist das ein nicht nur erwĂŒnschter, sondern beabsichtigter Nebeneffekt.

Zugriff auf Listenelemente

Der Zugriff auf die Listenelemente ist natĂŒrlich das A und O der Programmierung in unseren drei Lieblingssprachen. Tab. 1 faßt die elementaren Zugriffsmöglichkeiten in diesen Sprachen zusammen. VerstĂ€ndlicherweise ergibt sich in PROLOG die deutlichste Abweichung von LISP, weil der Zugriff auf die Fakten der Datenbank nur ĂŒber den Unifizierungsmechanismus (siehe Literaturliste 3) erfolgen kann. Die PrĂ€dikate nth/3 und cons/1 in Tab. lc sind benutzerdefiniert und sollten dem jeweiligen Verwendungszweck angepaßt werden.

Die Assoziationsliste

Eine besondere Form von Liste ist in LISP die sogenannte Assoziationsliste (LOGO: Property Liste). Sie ermöglicht das Speichern von miteinander verbundenen Elementen. Weiter unten benutzen wir eine Assoziationsliste, um einen deutschsprachigen Simpeltext in ein holpriges Englisch zu ĂŒbersetzen. Man speichert dann lediglich in einer Assoziationsliste die deutsch-englischen Assoziationen ab, also im unten aufgefĂŒhrten Beispiel:

((dies this) (satz sentence) (ist is) (ein a))

Das erste Element einer Assoziationssubliste wird SchlĂŒssel genannt (also: dies, satz, ist, ein). Verschiedene Listenfunktionen in LISP erlauben ein sehr effektives Arbeiten speziell mit dieser Listenform.

Funktion AusfĂŒhrung in LISP
Bindung der Liste (a, b, c) an das Symbol liste (setq liste ’(a, b, c)) oder (setq liste (list ’a ’b ’c))
Ausgabe des 1. Elementes
a
(car liste)
Ausgabe der Restliste (b, c) (cdr liste)
Ausgabe des 2. Elementes
b
(car (cdr liste)) oder (cadr liste)
Ausgabe des n. Elementes (nth n liste)
EinfĂŒgen eines neuen Elementes x in die Liste. Die neue Liste ist (x, a, b, c) (cons x liste)
AneinanderhĂ€ngen zweier Listen. Ergibt (a, b, c, d, e, f) (append ’(a, b, c) ’(d e, f))

Tabelle 1a: Elementare Listenoperationen in LISP

BĂ€ume als spezielle Listen

Wir haben schon gesehen, daß die Elemente von Listen wiederum Listen sein können. Diese Datenstruktur nennt man besser einen Baum. Zur Veranschaulichung soll uns die folgende Liste dienen:

(k1 (k2 b1 b2) (k3 (k4 b3 b4) (k5 b5 (k6 b6 b7))))

Den zugehörigen Baum zeigt Abb. 1. Es bedeuten hierin k1 - k6 die Knoten des Baumes, b1 - b7 die BlÀtter des Baumes. Kenner werden einen sogenannten BinÀrbaum wiedererkennen; solche, die es werden wollen, lesen bei Literaturliste 4 nach, k1 ist hier die Wurzel des binÀren Beispielbaumes.

Funktionen in LISP und LOGO

Wir verlassen nun erst einmal den gemeinsamen Teil und kĂŒmmern uns speziell um die Organisation eines LISP-bzw. LOGO-Programmes. PROLOG ist eine relationale Sprache, in der das Programm aus Fakten und miteinander verknĂŒpften Klauseln besteht, wĂ€hrend LISP und LOGO als funktionale Sprachen ihr Ergebnis aus dem sequentiellen Aufruf von Funktionen erhalten. Wie in Pascal gibt es auch LISP- und LOGO-Programmteile, die zwar behandelt werden wie Funktionen, aber keinen Funktionswert liefern. Sie heißen (wie in Pascal auch) Prozeduren. Allgemein gilt, daß Prozeduren dann keine Funktionen sind, wenn sie Nebeneffekte zeigen. SelbstverstĂ€ndlich gibt es auch in LISP und LOGO standardmĂ€ĂŸig vorgesehene Funktionen und Prozeduren; sie heißen Primitive, setq ist ein Beispiel fĂŒr eine LISP-Prozedur, die keine Funktion ist, weil sie als Nebeneffekt einen Wert (2. Argument) an ein Symbol (1. Argument) bindet. Die Primitive car und cdr in Tab. la sind natĂŒrlich Funktionen, die ein entsprechendes Atom bzw. eine Liste als Funktionswert zurĂŒckgeben. Und da sie ihr Argument nicht verĂ€ndern, haben sie auch keine Nebeneffekte. Tab. 2 zeigt eine Zusammenfassung aller Listenprimitive in XLISP mit Beispielen. Um Übersichtlichkeit zu wahren, werde ich hier lediglich die LlSP-Schreibweise erwĂ€hnen. Anhand der Tab. 1 sollte der Leser in der Lage sein, die entsprechende LOGO-Schreibweise zu erarbeiten. Die schon in Tab. 1 erwĂ€hnten Primitive car, cdr und cons bilden so etwas wie ein Funktions-Umkehrfunktionspaar. D. h., es gilt die IdentitĂ€t:

(cons (car liste) (cdr liste)) = liste

Mit cons wird also eine durch car und cdr aufgetrennte Liste wieder zusammengefĂŒgt. Bitte erinnern Sie sich, daß in einer Liste nicht nur Atome, sondern auch Listen als Elemente stehen können. So ist z. B. ((a b) (c d)) eine Liste, die aus zwei Elementen besteht: der Liste (a b) und der Liste (c d). Folglich ergibt (car '((a b) (c d))) den Funktionswert (a b), eine Liste als erstes Element, (cdr '((a b) (c d))) liefert dann logischerweise ((c d)), die Restliste, die die Liste (c d) als einziges Element enthĂ€lt. FĂŒr die in Tabelle 2 aufgefĂŒhrten Funktionen gibt es noch Optionen, deren Besprechung den Rahmen dieser EinfĂŒhrung sprengen wĂŒrde. Der Leser sei hier auf das XLISP-Manual verwiesen.

Funktion AusfĂŒhrung in LOGO
Bindung der Liste [A, B, C] an das Symbol LISTE MAKE "LISTE [A, B, C]
Ausgabe des 1. Elementes A, FIRST :LISTE
Ausgabe der Restliste [B, C] BUTFIRST :LISTE
Ausgabe des n. Elementes ITEM n :LISTE
EinfĂŒgen eines neuen Elementes X in die Liste. Die neue Liste ist [X, A, B, C] MAKE "LISTE (FPUT "X, :LISTE)

Tabelle 1b: Elementare Listenoperationen in LOGO

Funktion AusfĂŒhrung in PROLOG
Nimmt das Fakt, das [a, b, c] eine Liste ist in die Datenbank auf. assert(liste([a,b,c]).
Ausgabe des 1. Elementes der Liste in der Datenbank a liste([Erstes1]).
Ausgabe der Restliste [b, c] liste([...
Ausgabe des 2. Elementes b liste([...,Zweites
Ausgabe des n. Elementes liste(X),nth(n,X,Element).
mit: nth(1,[Kopf
EinfĂŒgen eines neuen Elementes x in die Liste in der Datenbasis. Die neue Liste ist [x, a, b, c] cons(x).
mit
cons(X):— liste(Y),assert(liste([X
AneinanderfĂŒgen zweier Listen. Ergibt Liste = [a, b, c, d, e, f] append([a, b, c],[d, e, f], Liste).

Tabelle 1c: Elementare Listenoperationen in PROLOG

Abb. 1: BinÀrer Beispielbaum

Evaluierung von LISP-Termen

ErfahrungsgemĂ€ĂŸ bereitet AnfĂ€ngern die Evaluierung von LISP-Termen große Schwierigkeiten. Deshalb möchte ich die in Literaturliste 2 recht kurz geratene EinfĂŒhrung hier ergĂ€nzen. Generell versucht LISP (genauer gesagt ein eval-Lisp), den Wert eines Terms zu erfahren, bevor es ihn weiterverarbeitet. Zur Anschauung betrachte man den XLISP-Dialog in Abb. 2. In der ersten Zeile wird das Atom A an den Wert 1 gebunden. Da ein Atom (eine Zahl ist ein numerisches Atom) zu sich selbst evaluiert, ist in der Anweisung kein Apostroph fĂŒr 1 erforderlich. Eigentlich mĂŒĂŸte das Symbol A mit einem Apostroph eingegeben werden, um dem Interpreter zu verdeutlichen, daß das Symbol A als unevaluiertes Atom verwendet werden soll. Dies ist nicht erforderlich, weil meist eine Bindung ohnehin nur an ein Atom erfolgt und LISP deshalb vorsorglich das erste Argument mit einem Apostroph versieht, setq ist schließlich nichts anders als die Kurzform von set quote. (setq a 1) ist also Ă€quivalent zu (set ’a 1). In der zweiten Anweisung wird schließlich das Atom B an die Liste (+ a 1) gebunden. Dies ist zwar die Anweisung, die Summe von a und 1 zu berechnen, da sie aber in der setq Anweisung quotiert wird, wird sie nicht ausgefĂŒhrt. Wachsame haben vielleicht bemerkt, daß hier bereits die in Pascal, C, Basic & Co. streng durchgefĂŒhrte Trennung von Programm und Daten verwischt. Hier dient eine Programmanweisung (addiere den Wert von a und 1) als Wert. LĂ€ĂŸt man die Quotierung fĂŒr das zweite Argument weg, dann wird die Evaluierung des zweiten Terms durchgefĂŒhrt. D. h., die Summe von A und 1 wird erst berechnet und dann das Ergebnis an C gefunden (dritte Anweisung). Das Ergebnis der vierten Anweisung zu verstehen, dĂŒrfte nun keine Schwierigkeiten bereiten: A evaluiert zu 1. C evaluiert zu 2 und die Summe ist 3. Wer nun in der fĂŒnften Anweisung (+ a b) ein vernĂŒnftiges Ergebnis erwartet, hat zu hohe Erwartungen an den XLISP-Interpreter. SelbstverstĂ€ndlich evaluiert XLISP den Term zu ( +1 (+ A 1)). aber die Evaluierung wird nicht rekursiv bis zur letzten Stufe durchgefĂŒhrt. sondern stoppt hier. Da die Addition zwei numerische Atome verknĂŒpfen will, (+ A 1) aber eine Liste darstellt, ist nun die Fehlermeldung bad argument type zu erwarten. Sorgt man mit eval b jedoch ausdrĂŒcklich fĂŒr eine Evaluierung des Termes 3. dann wird in der Tat die korrekte Summe ermittelt (sechste Anweisung):

(+ a (eval b)) — (+ a (+ a 1)) — (+ 1 2) - 3

Einige einfache Anwendungen

Ungeachtet der Tatsache, daß LISP keine Sprache ist, in der man bevorzugt rechenintensive VorgĂ€nge bearbeitet, betrachten wir als einfachstes Beispiel die Berechnung einer Wertetabelle. Dies lĂ€ĂŸt sich folgendermaßen erreichen:

(setq argumente ’(0.0 0.785398 1.04719 1.57079 3.14159)) (setq wertetabelle (mapcar sin argumente))

Diese zwei Zeilen berechnen den Sinus von 0,/4,ir/3,V2 und n . Die Funktionswerte findet man anschließend in der Wertetabelle wieder:

wertetabelle (0.000000 0.707106 0.866021 1.000000 0.000020)

Ein weiteres einfaches Beispiel unter Verwendung der Listenfunktionen ist die Übersetzung eines deutschsprachigen Texten in pitching english. D. h., man ĂŒbersetzt den Text wortweise und erhĂ€lt ein mehr oder weniger brauchbares Konglomerat englischer Worte, die im Idealfall einen lesbaren Satz bilden. Dazu stellt man sich zunĂ€chst ein Lexikon in Form einer Assoziationsliste zusammen, deren erste Element jeweils das deutsche Wort und dessen zweites Element das zugehörige englische Wort darstellen. Dann lĂ€ĂŸt man die Assoziationsliste die entsprechenden Substitutionen durchfĂŒhren und entfernt anschließend die störenden Klammern aus dem Text:

(setq deutsch_englisch '((dies this) (satz sentence) (ein a) (ist is)) ((DIES THIS) (SATZ SENTENCE) (EIN A) (IST IS)) (setq deutsch '(dies ist ein satz)) (DIES IST EIN SATZ) (setq englisch (sublis deutsch_englisch deutsch)) ((THIS) (IS) (A) (SENTENCE)) (setq englisch (mapcar car englisch)) (THIS IS A SENTENCE)

Die letzten beiden Zeilen lassen sich natĂŒrlich noch zu einer zusammenfassen:

(DIES IST EIN SA TZ) (setq englisch (mapcar car(sublis deutsch__englisch deutsch))) (THIS IS A SENTENCE)

Die eigentlich interessanten Anwendungen erhĂ€lt man allerdings erst, wenn man seine eigenen Funktionen definieren kann. Dazu kommen wir aber erst in der nĂ€chsten Folge. Dann nĂ€mlich geht es um die Definition von Funktionen und das LAMBDA-Konzept. Wie Sie sehen, bleiben wir also noch ein wenig im LISP/LOGO-Sprachraum. Erst wenn wir die PrĂ€dikatsfunktionen besprechen, werden wir unseren Blick wieder stĂ€rker in Richtung PROLOG Lenken. Schließlich ist PROLOG die Sprache zur Verarbeitung logischer PrĂ€dikate.

[1] Sarnow, K. EinfĂŒhrung in die kĂŒnstliche Intelligenz. ST-Computer 11/86.

[2] Sarnow, K. XLISP Review. ST-Computer 1/87

[3] Sarnow, K. TOY-PROLOG Review. ST-Computer 2/87.

[4] Wirth, Niklaus. Algorithmen und Datenstrukturen. B. G. Teubner, 1975.

append : Siehe Tabelle 1a.

assoc : Findet einen Term in einer Assoziationsliste. Beispiel: (setq arbeiter ’((name emil) (gehalt 1526.65))) (assoc ’gehalt arbeiter) (GEHA L T 1526.650000)

car : Siehe Tabelle 1a.

cdr : Siehe Tabelle 1a.

cxxr : xx bedeutet eine beliebige Kombination von a und d. z. B. cadr oder cdar oder cddr oder caar. Siehe Tabelle 1a.

cxxxr : Siehe cxxr und Tabelle 1a.

cxxxxr : Siehe cxxr und Tabelle 1a.

cons : Siehe Tabelle 1a.

last : Ergibt die Liste, welches das letzte Element enthĂ€lt. Beispiel: (last ’(a b c)) (c)

length : Gibt als Funktionswert die Anzahl der in der Liste enthaltenen Elemente an. Beispiel: (length ’(a b (c d))) 3

list : Der Funktionswert ist eine Liste der Argumente. Beispiel: (list ’a ’b ’(c d)) (a b (c d))

mapc : Wendet die Funktion (1. Argument) nacheinander auf die Listen der Argumentwerte (2. - n. Argument, eine Liste je Argument der Funktion) an. Als Funktionwert wird die erste Liste von Argumenten ausgegeben (2. Argument von mapc). Beispiel: (mapc + ’(1 2 3) ’(4 5 6))) (1 2 3) Man beachte, daß von der Summation nichts bemerkt wird, da die Funktion + (Addition) nebeneffektfrei ist und die Ergebnisse einfach vergessen werden. Diese Listenfunktion sollte deshalb nur bei Funktionen mit Nebeneffekt angewendet werden. Beispiel: (mapc (lambda (x y) (prinl (+ x y))) ’(1 2 3) ’(4 5 6)) 579(1 2 3) Uber die Bedeutung von lambda spĂ€ter.

mapcar : Wie mapc, allerdings wird hier als Funktionswert die Liste der Funktionswerte zurĂŒckgegeben. Beispiel: (mapcar + ’(1 2 3) ’(4 5 6)) (5 7 9)

mapl : Wie mapc, wendet die Funktion aber auf die cdr der Argumentlisten an. Beispiel: (mapl length ’(a b c)) (a b c) Man beachte auch hier, daß die Funktion Nebeneffekte haben muß, um eine Wirkung zu zeigen.

maplist : Wie mapcar, wendet die Funktion aber au die cdr der Argumentlisten an. Beispiel: (maplist length ’(a b c)) (3 2 1) Zuerst ist die Argumentliste (a b c) und deren LĂ€nge 3. Der cdr dieser Liste ist (b c), die LĂ€nge 2. Der cdr dieser Liste ist (c), die LĂ€nge 1. Dann bricht maplist ab, weil der folgende cdr NIL ist.

member : Findet einen Ausdruck in einer Liste und gibt die Restliste zurĂŒck. Beispiel: (member ’b ’(a b c)) (b c)

nth : Siehe Tabelle 1a.

nthcdr : Gibt den n-ten cdr einer Liste zurĂŒck. N = 0 ergibt die Originallfte. Beispiel: (nthcdr 2 ’(a b c d e f)) (c d e f)

remove : Entfernt einen Term aus einer Liste. Beispiel: (remove ’b ’(a b c)) (a c)

reverse : Kehrt eine Liste in der Reihenfolge ihrer Elemente um. Beispiel: (reverse ’(a b c)) (c b a)

sublis : Ersetze mit Hilfe einer Assoziationsliste. Beispiel: (sublis ’((halli hallo)) '(aber halb)) (ABER (HALLO))

subst : Ersetzt LISP Terme. Beispiel: (subst ’demo ’b ’(a b c)) (a demo c)

Tabelle 2a: Listenfunktionen in XLISP

delete : Löscht einen Term aus einer Liste. Beispiel: (setq liste ’(a b c)) (A B C) (delete liste ’b) (A C)

nonc : Vereinigt zwei Listen zu einer (physisch). Beispiel: (setq liste 1 ’(a b c)) (A B C) (setq liste2 ’(d e f)) (D E F) (nonc liste 1 liste2) (A B C D E F) liste 1 (A B C D E F) liste 2 (D E F)

rplaca : Ersetzt den car einer Liste. Beispiel: (setq liste ’(a b c)) (A B C) (rplaca liste ’b) (B B C) liste (B B C)

rplacd : Ersetzt den cdr einer Liste. Beispiel: (setq liste ’(a b c)) (A B C) (rplacd liste ’(d e)) (A D E) liste (A D E)

Tabelle 2b: Listenprozeduren in XLISP (destruktiv)

> (setq a 1) <-------------------A wird an den Wert 1 gebunden 1 > (setq b ’(+ a 1)) <-----------B wird an die Liste (+ A 1) gebunden (+A 1) > (setq c (+ a 1)) <------------C wird an den Wert der evaluierten 2 Liste (+ A 1) gebunden, d. h. an 2. > (+ ac) >----------------------A evaluiert zu 1 C evaluiert zu 2, 3 die Summe beider ergibt 3. > (+ a b) error: bad argumenttype - (+ A1) B evaluiert zu - AI), das ist der 1: > falsche Argumenttyp fĂŒr eine Addition. > (+ a (eval b)) >--------------Eval be. = _o zu (+ A1), dies wird 3 zu 2 evaluiert. A wird zu 1 evaluiert, > die Summe ergibt 3.

Abb. 2: Protokoll eines XLISP Dialoges zum Problem der Evaluierung

Karl Sarnow