254 40 14MB
German Pages 358 [360] Year 1985
de Gruyter Lehrbuch Hamann • Programmieren in LISP
Christian-Michael Hamann Einführung in das
Programmieren in LISP 2., bearbeitete und erweiterte Auflage Mit einem Anhang „LISP-Dialekte für Personal-Computer"
w DE
G Walter de Gruyter • Berlin • New York 1985
Dr.-Ing. Christian-Michael Hamann Klinikum Steglitz Freie Universität Berlin —Medizinische Informatik/GKZ— Hindenburgdamm 3 0 D-1000 Berlin 4 5
Das Buch enthält 6 3 Abbildungen
Für Bärbel, Sven und Niels
CIP-Kurztitelaufnahme der Deutschen Bibliothek Hamann, Christian-Michael: Einführung in das Programmieren in LISP/Christian-Michael Hamann. Mit e. Anh. „LISP-Dialekte für Personal-Computer". — 2., bearb. u. erw. Aufl. — Berlin; New York: de Gruyter, 1985. (De-Gruyter-Lehrbuch) ISBN 311010325 7 NE: Beigef. Werk
© Copyright 1984 by Walter de Gruyter & Co., Berlin 30. Alle Rechte, insbesondere das Recht der Vervielfältigung und Verbreitung sowie der Übersetzung, vorbehalten. Kein Teil des Werkes darf in irgendeiner Form (durch Photokopie, Mikrofilm oder ein anderes Verfahren) ohne schriftliche Genehmigung des Verlages reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfältigt oder verbreitet werden. Printed in Germany. Druck: Karl Gerike, Berlin. — Bindearbeiten: Dieter Mikolai, Berlin.
Geleitwort zur 1. Auflage
In letzter Zelt ist eine deutliche Zunahme der Bedeutung von LXSP festzustellen, verursacht durch das wachsende Interesse an Problemen der "Artificial Intelligence" und gefördert durch die Entwicklung der Computertechnik, die LISP-Dialekte für Mikrorechner und sogar LISP-Maschinen ermöglicht. LISP kann als "höhere Assemblersprache" bezeichnet werden : Sie verfügt Uber die Mächtigkeit einer problemorientierten Sprache, erlaubt jedoch gleichzeitig die Freiheit der Manipulation von Daten und Programmen wie in einer Maschinensprache. Hiermit verbunden ist allerdings auch der Zwang zur Aufmerksamkeit im Detail sowie eine gewisse Sprödigkeit im Zugang. "Eines der wirklichen Wunder von LISP besteht darin, daß es diese Sprache erlaubt, mit Ideen zu arbeiten" (J. Allen, BYTE, Aug. 1979). In diesem Sinne ist LISP nicht eine weitere Programmiersprache neben vielen anderen, und ein LISP-Lehrbuch kann nicht aus einer Aneinanderreihung von Vorschriften oder gar Rezepten bestehen. Vielmehr muß dieser Prozeß des Umsetzens von Ideen an ausführlich kommentierten Beispielen geübt werden ; der hier vorgelegte Text soll Begleiter sowie Ratgeber auch im Detail sein. Hervorgegangen ist dieses erste deutsch-sprachige LISPLehrbuch aus Vorlesungen, die Herr Dr. Hamann an der Freien Universität Berlin hält. Ich hoffe, daß auch der Leser etwas von jenem Engagement des Autors verspürt, das die Hörer seiner Vorlesung so begeistert und mitgerissen hat.
Berlin - Steglitz , Mai 1982
Peter Koeppe
Vorbemerkungen zur 2. Auflage
Die freundliche Aufnahme des Lehrbuches, die schon nach verhältnismäßig kurzer Zeit eine Neuauflage notwendig machte, zeigt, daß die gewählte Konzeption zur "Einführung in LISP" Anklang gefunden hat. Der Kern des Lehrbuches, die Implementierung einer "BlockWelt" (Kap. 3 bis 7)»
ist
nahezu unverändert
übernommen
worden : Einige Funktionen und Textstellen wurden verbessert, sowie das Merkblatt ( 2 )
zum 7. Kap. neu gestaltet.
Darüber hinaus enthält die Neuauflage, neben zahlreichen Verbesserungen
und
Ergänzungen
im
Detail,
folgende
Erweiterungen : - Definition von Funktionen zur ein- und mehr-dimensionalen Feldverarbeitung (Abs. 9.2) - Entwurf eines einfachen, modularen GO-Programms als Grundlage zur Entwicklung eines Experimentier-Systems (Kap. 8) - Erweiterung der "Rekursiven Paraphrasen" u.a. mit Funktionen für Property-Listen) Abs. 9.*0 - LISP-Maschinen und LISP-Dialekte für Personal Computer (A-1) - zusätzlich alphabetisches Verzeichnis der definierten Funktionen (in A-2) - Aktualisiertes und erweitertes Literaturverzeichnis unter besonderer Berücksichtigung einführender deutsch-sprachiger Veröffentlichungen zu LISP und "Künstlicher Intelligenz" (A-h)
Vorwort
(1) Ziel LISP (list-processing language) wurde bereits 1959 speziell für nicht-numerische Probleme, wie sie z.B. in der "Künstlichen Intelligenz" auftreten, geschaffen und ist die derzeit wichtigste
Symbol-Manipulations-Sprache.
LISP unterscheidet sich von den meisten anderen höheren Programmiersprachen dadurch, daß drei wichtige Eigenschaften in einer Sprache vereinigt sind : - Es können Datenstrukturen beliebiger Tiefe aufgebaut und verändert werden. - Funktionen können rekursiv definiert werden. - Es gibt in LISP keinen formalen Unterschied zwischen Daten und Programmen; daher ist es prinzipiell möglich, durch Programme neue Programme zu erzeugen und diese im gleichen Arbeitszyklus zur Ausführung zu bringen (z.B. Selbstoptimierung, Lernen). Ebensowenig
wie
eine
Fremdsprache
durch
Lesen
einer
Grammatik und eines Wörterbuchs zu lernen ist, kann die Programmiersprache LISP mit ihrer charakteristisch ausgeprägten Semantik und ihrem Nuancenreichtum durch das Studium der LISP-Funktionen aus einem Benutzerhandbuch beherrscht werden. Darum wird hier (im Kontext eines größeren und interessanten Problems ) durch Entwurf, Implementierung und Test eines vollständigen, exemplarischen Programm-Pakets (der Simulation eines intelligenten Manipulators in einer "Bauklötzchen-Welt" als formalisiertes Befehls- und Frage / Antwort-System) die Programmierung in LISP systematisch geübt. An Hand der vollständigen und ausführlichen Dialog-Protokolle ist der Leser auch ohne Rechner-Zugriff in der Lage, Zusammenhänge zu erkennen, Zweck und Anwendungsbreite der LISP-Funktionen zu verstehen und insbesondere rekursive Funktionsdefinitionen zu lernen.
VIII Sprachgrundlage ist INTERLISP, einer der wichtigsten LISP"Dialekte". Das bedeutet jedoch keine Einschränkung, da man sich mit den hier erworbenen Grundlagen-Kenntnissen schnell in andere Dialekte einarbeiten kann. Das Lehrbuch wendet sich nicht nur an Studenten der Informatik und Mathematik, sondern auch an diejenigen, für die Symbol-Manipulations-Sprachen wichtiges Handwerkszeug ihres Aufgabenkreises und Forschungsgebietes sind, wie z.B. Linguisten, Psychologen u.a. (2) Inhalt Das Lehrbuch ist aus der Vorlesungsreihe entstanden, die der Verfasser seit 1981 an der Freien Universität Berlin anbietet. Da sich der didaktische Ansatz bewährt hat, ist Darstellung und Einteilung des Lehrstoffs im wesentlichen beibehalten worden. Die neun Kapitel des Buches sind in drei Teile gegliedert : I II III
Einführung Implementierung einer "Block-Welt" Ergänzungen
Das Deckblatt zu jedem Kapitel enthält auf der Vorderseite ein ausführliches Inhaltsverzeichnis und auf der Rückseite ein "Merkblatt" zu einem wichtigen Thema dieses Kapitels. Im ersten Teil wird im 1. Kapitel ein orientierender, hinreichend ausführlicher Überblick zur Sprache und den Sprachelementen von LISP gegeben. Übungsaufgaben mit Lösungen sollen den Lernprozeß unterstützen. Im 2. Kapitel wird im ersten Abschnitt der Formalismus der Funktionsdefinitionen ausführlich geübt ; im zweiten (mit der Simulation des Puzzles "Die Türme von Hanoi") ein bereits komplexes, aber noch leicht überschaubares "Programm-System" als typische LISP-Lösung präsentiert. Hier wie in allen folgenden Kapiteln ist jedem Abschnitt das originale Dialog-Protokoll einer Terminal-Sitzung zu-
IX geordnet : Der Leser schaut gleichsam dem Lehrer am Bildschirm "über die Schulter". Die einzelnen Benutzereingaben werden vom LISP-System fortlaufend numeriert.
Auf diese bezieht sich der zuge-
hörige erklärende Text, der vor oder nach den (eingerahmten) Protokoll-Seiten zu finden ist. Ein Vorteil der Trennung von Protokoll und Text ist die Übersichtlichkeit beim Nachschlagen. Um Zusammenhänge leichter zu erkennen, wurde nach Möglichkeit Zusammengehöriges (z.B. Funktionsdefinition und -Test) auf einer Doppelseite angeordnet. Da der Verfasser auf die Druckqualität der Protokolle keinen Einfluß hatte, außerdem ein "Zusammenschneiden" notwendig ist, wenn man aussagekräftige und von Eingabefehlern bereinigte Listen erstellen will, mußten nahezu alle per Hand "restauriert" werden. Dabei waren gelegentlich kleinere Mängel nicht zu vermeiden. Der zweite Teil . die Implementierung einer "Block-Welt", ist das zentrale Thema dieses Lehrbuchs. Zunächst werden die von Winston in seinem Buch "Artificial Intelligence" /Wn77/ angegebenen Funktions-Module in INTERLISP transformiert. Anschließend werden alle notwendigen Strukturen initialisiert, Hilfsfunktionen definiert und mit Hilfe dieser die noch fehlenden Prozeduren für eine arbeitsfähige erste Version der "Block-Welt" formuliert. Schrittweise kommen wir von ganz einfachen zu immer komplexeren Strukturen, bis endlich ein "intelligentes" Frage/AntwortSystem geschaffen ist. Dabei lernt der Leser auf "natürliche" Weise die Sprache LISP kennen, indem folgende Fragen beantwortet werden : -
Welche Systemfunktionen stehen zur Verfügung ? In welchem Zusammenhang werden sie benutzt ? Was leisten sie ? Was benötigen wir darüber hinaus an Funktionen zur Lösung des gestellten Problems ? - Wie definieren wir diese ? - Welche Methoden sind anzuwenden ?
X Die zu definierenden Funktionen (Namen und Variablen wurden entsprechend der angelsächsischen Systemumgebung gewählt) sind nach didaktischen Gesichtspunkten entworfen. Grundsätzlich wurde "Durchsichtigkeit" angestrebt j der Verfasser hat dafür in Kauf genommen, daß insbesondere zu Beginn einige Funktionen (z.B. SPACE-LIMITS) wie FORTRANProgramme in LISP-Schreibwelse aussehen. Der dritte Teil ist (bis auf die Frage-Funktion SAY) vom zweiten Teil unabhängig und kann zu jedem beliebigen Zeitpunkt durchgearbeitet werden. Kapitel 8 enthält (als Herausforderung) den Projekt-Vorschlag zum Entwurf eines G0Spiel Programms. Im 9. Kapitel werden "destruktive" Systemfunktionen vorgestellt, definiert,
sowie
Funktionen
zur
Feldverarbeitung
eine Funktion zur Muster-Erkennung (mit
Anwendungsbeispielen) programmiert. Insbesondere der letzte Abschnitt dürfte
für
den Anfänger
sofort von Interesse
sein : Hier werden "Rekursive Paraphrasen" einiger Systemfunktionen formuliert. Als "Beispiel-Definitionen zum Nachschlagen" sind sie am Ende in alphabetischer Reihenfolge geordnet. Da es inzwischen brauchbare "LISP-Dialekte für Personal Computer" gibt, werden im Anhang Testberichte und deren Ergebnisse zu diesem Thema vorgestellt. Des weiteren sind (als Index) systematische und alphabetische Übersichten zu den 1k3 definierten (eigenen) Funktionen und den 88 verwendeten Systemfunktionen angegeben. Das Literaturverzeichnis enthält nur die wichtigsten und aktuellen Quellen (in denen wiederum ausführliche Literaturhinweise zu finden sind) unter besonderer Berücksichtigung deutsch-sprachiger Veröffentlichungen zu LISP und "Künstlicher Intelligenz". Auf der letzten Seite ist die "Situation 0" der "BlockWelt" zur bequemen Referenz angefügt. SIEMENS-INTERLISP ist ein sehr leistungsfähiges System, das neben dem Interpreter über Compiler, Editor, Unterbrechungs- und
Fehlerbehandlungsmöglichkeiten
verfügt.
Zur
XI Systemumgebung gehören auch ein "Programmer's Assistant", der als "aktiver" Partner über die Befehle Buch führt und auf Wunsch Befehle und deren "Seiten-Effekte" (mittels UNDO) rückgängig machen kann, sowie die DWIM-("Do-What-I-Mean") Fähigkeit, mit der eine Vielzahl von Eingabe-Fehlern abgefangen und automatisch korrigiert werden kann. Um den Text möglichst allgemeingültig zu halten, werden wir nicht auf diese Werkzeuge eingehen (allein die Besprechung des Editors belegt im Benutzerhandbuch /Ko8l/ 58 Seiten). Von der Menge der verfügbaren Systemfunktionen werden wir nur eine Auswahl kennenlernen . Wir beschränken uns dabei aber nicht nur auf den (theoretisch interessanten) "funktionalen Kern" von LISP, sondern stellen auch die "iterativen" und "destruktiven" Funktionen vor, die zum Schreiben leistungsfähiger Programme für die Praxis benötigt werden. Programmieren in LISP macht Spaß ! Trotzdem will dieses einführende Lehrbuch "erarbeitet" werden. Es soll den Leser auch an die englisch-sprachige und weiterführende LISPLiteratur heranführen, vor allem aber ihn in die Lage versetzen, eigene Probleme mit Hilfe des Benutzerhandbuches seines ihm zugänglichen LISP-Systems formulieren zu können. Konstruktive Kritik, Hinweise auf Fehler und Verbesserungsvorschläge sind dem Verfasser stets willkommen ! ( 3 ) Danksagung Das vom Verfasser benutzte LISP - SIEMENS-INTERLISP (V. ^.o) wurde von der Fa. Siemens zu Testzwecken zur Verfügung gestellt. Dieses LISP ist Nachfolger der Version 3 ; es läuft auf dem Siemens-Rechner 7.5^1 des Dialogsystem Süd (DSS) der Freien Universität Berlin (FUB) unter dem Betriebssystem BS 2000 (V. 7.1) Der Zugriff erfolgt mittels Display-Terminal mit AkustikKoppler über Wählleitung und mittels 8160-Terminal über Standleitung.
XII Für die großzügige Unterstützung durch Bereitstellung von Betriebsmitteln sei dem DSS, Herrn J. Reker
und seinen Mit-
arbeitern, sowie der Zentraleinrichtung für Datenverarbeitung (ZEDAT) an der FUB, Herrn A.Giedke
und seinen Mitar-
beitern Dank ausgesprochen. Für wertvolle Hilfe und Anregungen ist den Herren D. Kolb und Dr. K. März von der Siemens AG
München zu danken.
Zahlreiche Verbesserungsvorschläge kamen aus den Reihen der Studenten. F. Wunderlich
Stellvertretend
möchte
ich
hier
Herrn
nennen und Dank sagen.
Für die Durchsicht der ersten Version des Manuskripts und viele
nützliche
Hinweise
sei
den Herren
Prof. Dr. W.
Brecht von der Technischen Fachhochschule Berlin und H.B. v.Schweinichen von der FUB herzlich gedankt. Besonderer Dank gilt Herrn Prof. Dr.-Ing. P. Koeppe : Dieser hat vom ersten Entwurf des Vorlesungsskripts bis zum fertigen Buch alle Phasen der Entwicklung miterlebt, als kritischer Gesprächspartner und geduldiger Leser wesentliche Anregungen gegeben und das Entstehen dieses Buches im Rahmen des Forschungsvorhabens "Maschinelle Intelligenz" (MAIN - Projekt) sehr gefördert. Nicht zuletzt muß die angenehme Zusammenarbeit mit dem Verlag de Gruyter erwähnt werden : Der Verfasser ist Herrn W. Schuder und seinen Mitarbeitern zu Dank verpflichtet für das ihm entgegengebrachte Vertrauen und die gewährte Freiheit zur Gestaltung des Buches.
Berlin-Steglitz, August 1984
Christian-M. Hamann
Inhaltaüberaicht
v
Geleitwort Vorbemerkungen zur 2. Auflage
VI VI1
Vorwort Inhaltsübersicht
XIII
E I N F Ü H R U N G
1
1. Kapitel
3
Einführende Übersicht
5
Übungen zur "Einführenden Übersicht"
2. Kapitel
36
53
Beispiele zur Definition von Funktionen
55
Implementierung des Puzzles "Die Türme von Hanoi"
73
Übungsaufgaben
83
IMPLEMENTIERUNG EINER
" B L O C K - W E L T "
3. Kapitel
85 87
Transformation der von Winston angegebenen "Block-Welt" Funktionen auf INTERLISP
89
Eingabe der Properties für eine definierte "Situation 0"
98
Definition einer Funktion zur Ausgabe der Situations-Tabelle
102
Definition einer Funktion, die die "Block-Welt" aus jeder Fehler-Situation in die "Situation 0" zurücksetzen kann
111
XIV Kapitel
119
Definition von Hilfsfunktionen zur Erkennung von verfügbarem Platz im dreidimensionalen Raum der "Block-Welt"
122
Definition der für eine arbeitsfähige "Block-Welt" noch notwendigen Funktionen
135
Testlauf der ersten (arbeitsfähigen) "Block-Welt"
153
5. Kapitel
159
Reorganisation der "Block-Welt" Funktionen, um die zu einer Handlungskette erforderlichen Aktionen als "Trace" zu erhalten
161
Bindung des "Trace" an eine Liste als Voraussetzung zur Frage/Antwort-Fähigkeit des Systems
17^
6. Kapitel
181
Übungen zur Manipulation in Baum-Strukturen, Test-Definitionen der Frage-Funktionen
183
Definition der erweiterten Frage-Funktionen mit "Spezifizierung" und "Fokussierung" des Dialogs
202
7. Kapitel
213
Erweiterung des Frage/Antwort-Systems, Übungen zu Funktionsdefinitionen mit funktionalen Parametern
216
Automatisches Retten der Situationen und Rücksetzen im Fehlerfall als Voraussetzung zur Anwendung ziel-orientierter Such-Strategien
223
Einfache Funktionen zur Definition von Oberbegriffen
236
E R G Ä N Z U N G E N
2^3
8. Kapitel
2^5
Entwurf eines einfachen, modularen GO-Programms als 2^9 Grundlage zur Entwicklung eines Experimentier-Systems
XV 9. Kapitel Beispiele für "destruktive" Systemfunktionen
267 2J0
Definition von Funktionen zur ein- und mehr-dimensionalen Feldverarbeitung
2fh
Definition einer Pattern-Match Funktion, Anwendungsbeispiele zur Muster-Erkennung
287
"Rekursive Paraphrasen" einiger Systemfunktionen
297
Anhang
321
LISP-Maschinen und LISP-Dialekte für Personal Computer
325
Systematisches und alphabetisches Verzeichnis der definierten Funktionen
329
Alphabetisches Verzeichnis der verwendeten Systemfunktionen
335
Literaturverzeichnis
3^0
Die "Situation 0" der "Block-Welt"
3^3
Jedes Deckblatt eines Kapitels enthält ausführliches Inhaltsverzeichnis
EINFÜHRUNG
2
C 0 N S £ N Q U L L
D A L I S C A C D D F S A M 0 £ F F 0 R B A N E C D P D R A P E L N Y C £
A P P £ N £ D V A L
Q R U 0 P T L E C L A D I C R S A T
L E N G T H
A T 0 M
111111
1111111 1111111 11111
11111 11111
11111 11111
11111 11111
111111111 111111111 111111111
I N H A L T 1.1
Einführende Übersicht
1.1.1
Einleitung
1.1.2
Darstellung von Listenstrukturen
5 5
1.1.2.1
Syntaktische Darstellung
10
1.1.2.2
Interne Darstellung
11
1.1.3
Generelles zu LISP-Funktionen
12
1,1.k
Elementarfunktionen zur Listenverarbeitung
15
1.1.5
Property-Listen
1.1.6
Assoziations-Listen
1.1.7
Prädikatfunktionen
'9
1.1.8
Die LAMBDA-Funktion
20
1.1.9
Definitionen benannter Funktionen
21
1.1.10
Eine Steueranveisung
22
1.1.11
Rekursive Funktionsdefinitionen
23
1.1.12
Iterative Funktionsdefinitionen
2h
1.1.13
MAP-Funktionen
25
1.1.1!»
Beispiele zur Semantik in LISP
26
1.1.15
LISP-Dialekte und Literaturhinweise
27
1.1.16
Demonstration eines Übungsbeispiels
29
1.2
Übungen zur "Einführenden Übersicht"
36
1.2.1
Aufgaben
36
1.2.2
Lösungen
^
1®
h M E R K B L A T T
zum
1. Kapitel
Für den Zugriff zum SIEMENS-INTERLISP System ist folgende Hierarchie zu durchlaufen:
Organisatorisches zum Rechenzentrum (Zuteilung einer Benutzer-Nummer) Zugang zu einem Terminal LOGON / LOGOFF - Prozedur (Kommando-Ebene des BS 2000) /DO $RZP , LXSP (Zugriff und Verlassen des SIEMENS-INTERLISP Systems) (EXIT)
Strukturen zu den Übungsaufgaben und Lösungen
ISOHNER&TAÄI 1 1 1
-TT7I
L,
1I
gamm«
DELTA
_L
NET:
I SftMSTft&l BETA
ALPHR
HIEMSTAG1 I « | MONTAS I
A SOWUTATI
EPSILON
TREE ••
..A.
B" p' L1S2. : (
A
H ( B ( M h i ) ) ( E ( ] K ) ) )
0
1
1 1
111
3
"G "e
I
3
r' k
L
M
'"& N
( C ( T ( L M ) ) ( & U O ) ) )
3111
2
3
32 2
3
QA
aa
CD—CO
A
B
D
H
I
E
•aa
LD—CD
^
K
C
F
L
M
G
)
1210
Tree :
CD
0
N
O
5 1.1 Einführende Übersicht
1.1.1 Einleitung Allgemein bekannte Aufgaben für Computer sind Lösungen arithmetischer Problemstellungen. Höhere Programmiersprachen für diese technisch-wissenschaftlichen Zwecke sind z.B. FORTRAN und ALGOL. Für kaufmännisch-verwaltungstechnische Belange ist die Textverarbeitung z.B. zum Erstellen von Lagerlisten, Rechnungen, Gehaltsnachweisen usw. von Bedeutung. Für diese Problem-Klasse wurde die höhere Programmiersprache COBOL entworfen. Inzwischen gibt es für nahezu jeden Schwerpunkt des ComputerEinsatzes (z.B. Prozeßdatenverarbeitung in Echt-Zeit) adäquate höhere Programmiersprachen (z.B. PEARL). Moderne Sprach-EntWicklungen wie z.B. ADA sollen möglichst alle Anwendungsbereiche abdecken, um so eine Vereinheitlichung und Kosten-Reduzierung bei Programm-Entwicklung und -Wartung zu erreichen. Im Gegensatz zu diesen üblichen Aufgaben für Computer, bei denen eindeutige, eine Lösung garantierende Algorithmen angebbar sind, gibt es Probleme meist nichtnumerischer Art, für deren Lösung kein Rezept bereit liegt. Hier helfen z.B. "heuristische" Verfahren, also Regeln, die sich beim Problemlösen bewähren, auch wenn keine strenge mathematische Begründung möglich ist oder eine Lösung (falls sie existiert) nicht immer garantiert werden kann. Derartige Probleme lassen sich oft in Baum-Struktur (vgl. D.E. Knuth /Kn72/ ) darstellen, wie z.B. bei Spielen mit ihren
6
1.1.1
Zügen und Gegenzügen. Selbstverständlich müßte ein mathematisches Programm theoretisch den jeweils besten Zug berechnen können, jedoch würde es bei komplexen Spielen (wie z.B. Schach oder Dame) Jahrtausende dauern. Hier hilft nur eine
Heuristik , die Züge und Gegenzüge bis
in eine gewisse Tiefe verfolgt und dann (wie der Mensch) eine Auswahl trifft nach Kriterien der "Feldbeherrschung", "Bedrohung" usw. Ein erfolgreiches Beispiel dieser Methode ist das Dame-Spiel-Programm von A.L. Samuel(1959),
das
inzwischen (dank seiner Struktur) gelernt hat, besser zu spielen als ein menschlicher Gegner. (Samuels Aufsatz ist, zusammen
mit
anderen
interessanten
Beiträgen,
in
dem
historischen Standardwerk /FF63/ zu finden.) Betrachten wir ein weiteres Beispiel zur Illustration dieser sog. "symbolischen" Datenverarbeitung: Für einen Schrift-Erkennungs-Automaten, der auch ein schlecht gedrucktes "A" als "A" erkennen soll, ist die Programmierung einer (statistischen) Vergleichs-Methode mit der Schablone des "richtigen A" auch bei extremem Aufwand wenig brauchbar. Besser ist eine "semantische Analyse", bei der das Programm als "A" einen Buchstaben erkennt, der z.B. so beschrieben ist: "Zwei etwa parallele, etwa senkrechte Linien, die unten auseinander stehen und sich oben berühren und ungefähr in der Mitte eine waagerechte Verbindung haben". Ein solches Programm ist selbstadaptierbar und liefert auch dann brauchbare Ergebnisse, wenn sich die Eingabedaten stark geändert haben. Das Spiel-Programm und das Schrift-Erkennungs-Programm sind Beispiele für ein wichtiges Anwendungsgebiet der nicht-numerischen Datenverarbeitung, das als "Maschinelle Intelligenz" oder "Künstliche Intelligenz"
(Artificial
Intelligence, AI) oder auch (nach einem Vorschlag von W. Bibel) als "Intellektik" bezeichnet wird.
1.1.1
7
AI beschäftigt sich mit Problemen, die - wenn sie von Menschen gelöst werden - "Intelligenz" erfordern. Wichtige Teilgebiete der AI-Forschung sind: Allgemeine Methoden zum "Problem-Lösen", Muster-Erkennung, mathematisch-logische Beweis-Verfahren, Roboter-Technologie, Natürliche Sprachverarbeitung, Expertensysteme. Insbesondere "Expertensysteme" (das sind "Wissens-Basen", die mittels Inferenzkomponenten auch nicht-explizit gespeichertes Faktenwissen nach Regeln ableiten und verfügbar machen können) demonstrieren den erfolgreichen Einsatz von AI-Methoden (vgl. z.B. /Wn77/). Beispiele (in LISP) sind: - Das Mathematik-Programm MACSYMA beherrscht (u.a.) symbolische Differentiation und Integration auf Expertenebene. - Das Programm-System DENDRAL ist Experte zur Bestimmung der Molekül-Struktur aus den Daten des Massenspektrogramms. - Das Programm MYCIN unterstützt den Arzt bei Diagnose und Therapie von Infektionskrankheiten. Da die Systeme ihre Entscheidung begründen, werden sie auch als Tutoren zur Ausbildung eingesetzt. Darüber hinaus sind mit Meta-DENDRAL und EMYCIN generalisierte Versionen entwickelt worden, die aus "diffusem Wissen" Regeln ableiten können. Mit Hilfe dieser "Shells" sind Expertensysteme für andere Fachgebiete relativ schnell zu implementieren. Methoden und Ziele der AI sind von allgemeinem Interesse und spielen in der heutigen Datenverarbeitung eine zunehmende Rolle: Die künftigen sehr komplexen InformationsSysteme können nicht mehr mit konventionellen Mitteln der Informatik beherrscht werden. AI-Programme modellieren entsprechende Theorien. Einerseits sind Programme präzise Experimentier-Werkzeuge, womit Theorien gestützt oder verworfen oder zur Modifi-
8
1.1.1
kation gezwungen werden können. Andererseits haben AIProgramme noch weitgehend experimentellen Charakters Von der Unsicherheit über Ziele und zu benutzende Methoden beim ersten Programm-Entwurf wird über erreichte Zwischenstadien die Programm-Entwicklung durch neu gewonnene Erkenntnisse gesteuert. Aus dem zuletzt genannten Grund werden an AI-Sprachen andere Anforderungen gestellt als an die konventionellen höheren Programmiersprachen, die für "produktionsreife" Anwenderprobleme konzipiert wurden. (Darum ist z.B. ADA für AI-Applikationen wenig geeignet, wie der SRI-Report /SM80/ feststellt.) Von den AI-Sprachen der "ersten Generation" (z.B. LISP, SAIL, POP-2, SNOBOL) ist LISP (Iist-processing language) die wichtigste und weitverbreitetste
Symbol-Manipulations-
Sprache und grundlegend zum Verständnis darauf aufbauender Sprachen der "zweiten Generation" (z.B. MICRO-PLANNER, CONNIVER, FUZZY). Die erste Version von LISP wurde am Massachusetts Institute of Technology (MIT) unter J. McCarthy entwickelt: Das
"LISP -
Programmer's Manual" hat bereits 1959 als handschriftlicher Entwurf vorgelegen. Die Bedeutung von LISP unterstreichen folgende Zitate : - P.C. Jackson /Jajk/ stellt fest! "Der Wert guter Programmiersprachen für die Entwicklung des AI-Forschungsgebietes kann gar nicht hoch genug eingeschätzt werden. Ohne LISP hätte AI nicht 'vom Boden abheben' können." - P.H. Winston/Wn77/ formuliert das so: "LISP ist die Mathematik der AI. AI ohne LISP ist wie Physik für Poeten laudabel und nützlich, aber nicht ganz ernst zu nehmen." - L. Sikl6ssy/Si76/zitiert J.E.Sammet (/Sa69/): "Programmiersprachen können in zwei Kategorien eingeteilt werden : In der einen Kategorie ist LISP und in der anderen sind alle anderen Programmiersprachen."
9
1.1.1 LISP unterscheidet sich von den meisten anderen höheren
Programmiersprachen dadurch, daß drei wichtige Eigenschaften in einer Sprache vereinigt sind : - Es können Daten-Strukturen beliebiger Tiefe (z.B. als binäre Bäume) aufgebaut und verändert werden. Infolge dynamischer Speicherverwaltung stößt ein eskalierendes Anwenderprogramm nicht an Grenzen vorgegebener Feldgrößen. - Funktionen können rekursiv definiert werden. Bekanntes Beispiel einer rekursiven Definition ist die Fakultätsfunktion : n! = n * (n-1)!
für
n > 0
mit
0! = 1
per def.
- Es gibt in LISP keinen formalen Unterschied zwischen Daten und Programmen. Daher ist es möglich, durch Programme neue Programme zu erzeugen, oder Programme sich selbst verändern zu lassen und diese im gleichen Arbeitszyklus zur Ausführung zu bringen. Somit ist prinzipiell die Möglichkeit gegeben zur Strukturveränderung des Programms durch Selbstoptimierung, Selbstprogrammierung, Selbstlernen. Eine weitere nützliche Eigenschaft s - LISP ist eine typfreie Sprache Die Datentypen müssen nicht vom Programmierer explizit deklariert werden; welcher Datentyp jeweils vorliegt wird vom System selbständig erkannt. Das Erlernen von LISP wird durch eine extrem einfache Syntax erleichtert. Kenntnisse anderer Programmiersprachen werden nicht benötigt ; im Gegenteil s
"Vorkenntnisse
sind oft ein Handicap" (Winston /Wn77/).
Die "Einführende Übersicht" ist die überarbeitete und erweiterte Fassung des Artikels : Hamann, C.-M. "Die Programmiersprache LISP - Eine einführende Übersicht" Elektronik, 1(1982)99-102, 2(1982)60-64 (Mit freundlicher Genehmigung des Franzis Verlag, München)
10 1.1.2 Darstellung von Listenstrukturen
1.1.2.1 Syntaktische Darstellung Daten und Programme in LISP werden als "S-Expression" (symbolischer Ausdruck) geschrieben. Eine S-Expression ist z.B. ein "Atom" oder eine "Liste". Ein Atom ist entweder ein literales Atom oder eine Zahl. z.B. : A
=
literales Atom
BANANE
=
literales Atom
1ETWASSELTSAMESATOM
=
literales Atom, da keine Zahl
2
=
ganze Zahl (integer)
3.1ͻ16
=
dezimale Zahl (Real)
Als Liste kann beispielsweise der Inhalt einer SchUssel beschrieben werden: (APFEL BANANE CITRONE) oder "abstrakt": (A B C) Eine Liste ist entweder leer oder enthält Atome und/oder Sublisten, z.B.: ( )
=
NIL
=
leere Liste, ist mit dem Atom NIL identisch !
(D(E F)G)
=
Liste mit Atom D, der Subliste (E F) und dem Atom G
Listenelemente sind in Klammern eingeschlossen. Eine hierarchische Ordnung wird durch die Einbettung von Sublisten ausgedrückt.
1.1.2.1
11
Durch Numerierung der korrespondierenden Klammer-Paare (per Hand ! ) ist die "Schachtel-Tiefe" leicht zu ersehen, z.B. : ( A ( X Y ) ( D ( E F ) G ) H ) 0 1 1-1 2 1 1 0 Diejenigen Elemente einer Liste, die durch das O-KlammerPaar eingeschlossen sind, heißen "top-level" Elemente. In dieser Liste sind das: A
das Atom A
(X Y)
als Subliste
(D(E F)G)
als Subliste
H
das Atom H
Der Numerierungs-Modus wird im folgenden Abschnitt deutlich.
1.1.2.2 Interne Darstellung Man kann sich ein Listenelement als aus einer DoppelZelle bestehend vorstellen, die zwei Zeiger (pointer) enthält. Der linke Zeiger verweist auf den "Inhalt", der rechte Zeiger verweist auf das nächste Listenelement. Das Listenende ist durch den Zeiger auf das Atom NIL gegeben. Beispiel einer linearen Liste, z.B. (A B C): i p A
B
C
Statt des NIL-Zeigers zeichnet man der besseren Übersicht wegen in die letzte Zelle einen diagonalen Strich. Wie leicht zu erkennen ist, können Änderungen in der Listenstruktur einfach durch Änderung der Zeiger vollzogen werden. Aus der Liste (A B C) wird z.B. die Liste
12
1.1.2.2
(A z c), wobei die auf B zeigende Zelle wieder dem System zur freien Verfügung zurückgegeben werden kann
("garbage
collection" = "Müll-Sammlung") :
r B
JZ\
T
c
z
"garbage" Beispiel einer hierarchischen Liste
(vgl. Beispiel des
letzten Abschnitts) ( A ( X Y ) ( D ( E F ) G ) H )
FEH
LZ
171
XZ i-*UZl L E X
Y D
r E
s top-level
0 > C 0
T F
G H
(o)
level
1
level
2
Atome (sind Unikate ! )
1.1.3 Generelles zu LISP-Funktionen Der hier vorgestellte moderne LISP-"Dialekt"
(genaueres
dazu in Abs. 1.1.15) heißt INTERLISP. Der Benutzer arbeitet
interaktiv
( daher
der
Name ) mit
dem
LISP -
Interpreter und initialisiert die normale Arbeitsschleife "Einlesen - Auswerten - Drucken"
(read-eval-print).
In einer (zu evaluierenden) Liste wird das erste Atom als Funktionsname angesehen, die restlichen Elemente als deren Argumente. Beispiele für einige arithmetische Funktionen verdeutlichen das Prinzip :
1.1.3
13
(PLUS 5 3)
•
8
(TIMES 5 3 2)
•
30
(DIFFERENCE 5 3 )
•
2
(MINUS 5)
•
-5 6
(ADDI
5)
k
(SUB1 5 )
Es handelt sich hier um Präfix-Notation, die vom polnischen Logiker J. Lukasiewicz ( 1 9 2 5 ) begründet wurde. (Die Schul-Algebra benutzt Infix-, ein HP-Taschenrechner Postfix-Notation, auch "umgekehrte polnische Notation"= UPN genannt.) Hervorzuheben ist, daß es in LISP Funktionen gibt (wie z.B. PLUS und TIMES), die beliebig viele Argumente akzeptieren! Schachtelungen werden "von innen nach außen" abgearbeitet (evaluiert), z.B.: (TIMES(PLUS 5(ADD1 3))(MINUS 2 ) )
•
-18
Mit der Funktion SETQ kann eine Wertbindung an eine Variable bewirkt werden, z.B. A=5 , B=3 , C=2 s (SETQ A 5) (SETQ B 3) (SETQ C 2) Wird jetzt A oder B eingegeben, so wird der gebundene Wert zurückgegeben. Man kann in weiteren Anweisungen darauf zurückgreifen, z.B.: A
5
(PLUS A B )
•
8
Soll eine Variable als Wert eine Liste zugewiesen bekommen, so muß der Evaluierungs-Prozeß ("erstes Atom ist Funktionsname") außer Kraft gesetzt werden. Das geschieht mittels Hochkomma (quote-mark). z.B.: (SETQ LISTE1
•(A B C) )
14
1.1.3
Wird jetzt der Name des Atoms LISTE1 eingegeben, so wird als der daran gebundene Wert, die Liste
zurückgegeben:
LISTE 1
(ABC)
Das Hochkomma ist eine vom Rechner akzeptierte KurzSchreibweise der Funktion QUOTE, die ihr Argument
nicht
evaluiert. Die oben angegebene Zuweisung wäre in ausführlicher
Schreibweises
(SETQ LISTE1
(QUOTE (A B C)))
Die hier offensichtlich lästige und
fehleranfällige
Klammerzählung kann stets durch "Superklammern" vereinfacht werden. Dem obigen Beispiel äquivalent
ist:
(SETQ LISTE 1 • (A B C > Anmerkung: Zahlen definieren sich selbst,
evaluieren
darum zum gleichen Wert. Weiterhin folgt wegen des quotemark, daß das zweite Argument von SETQ auch eine beliebige S-Expression sein kann, deren Wert
(nach Auswertung) an
das erste Argument gebunden wird. Mit dem Beispiel von oben A=5
, B=3 ergibt
sich:
(SETQ SUM (PLUS A B)) SUM
•
8
•
(PLUS A B)
Man beachte also folgenden Unterschied: (SETQ SUM SUM
'(PLUS A B))
Es ist bemerkenswert, daß die hier als "Datum" an SUM gebundene Liste auch als "Programm" interpretierbar ist ! Mit der Funktion E V A L kann dieses zur Ausführung
gebracht
werden : (EVAL SUM)
•
8
Dieses einfache Beispiel zeigt die in der Einleitung erwähnte Ambivalenz von Daten und Programmen in LISP .
15 1.1.4 Elementarfunktionen zur Listenverarbeitung Betrachten wir unsere bekannte LISTE 1 als ZeigerDiagramm:
CDR
Zeiger auf Rest-Liste
M Zeiger auf
0
CAR
erstes Listen-Element
Die Funktion CAR liefert das erste Element einer Liste, die Funktion CDR die Restliste, z.B.: (CAR ' ( A B C ) )
•*•
A
(CDR ' ( A B C ) )
-»•
(B C)
•
A
oder: (CAR LISTE1) (CDR LISTE 1)
(B C)
Die merkwürdigen, nicht-mnemotechnischen Funktionsnamen CAR (gesprochen: kahr) und CDR (gesprochen: kuder) haben ihre
historische
Ursache
in
der Wortstruktur
der
IBM 704 : "contents of address part of register"
und
"contents of decrement part of register" . Bei wiederholter Verwendung der Funktionsnamen ("von innen nach außen" anzuwenden !) (CAR(CDR • (A B C >
B
(CAR(CDR(CDR • (A B C >
C
sind die zusammengesetzten Funktionsnamen praktisch, wobei zwischen C ... R ein A für CAR, ein D für CDR steht:
16
1.1 (CADR ' ( A B C ) )
B
(CADDR ' ( A B C ) )
•
C
(CAADDR '(A(X Y)(D(E F)G)H) )
-»•
D
Mit den Funktionen CAR und CDR können Listen durchsucht mit der Funktion CONS (construct) kann eine Liste gebil det oder erweitert werden, z.B.: (CONS 'A NIL)
•
(A)
(CONS 'A ' (B C) )
(A B C)
Man beachte die Äquivalenz : (CONS(CAR '(A B C))(CDR •(A B C)))
*
(A B C)
Wir können auch hier die Ambivalenz von "Daten" und "Programm" demonstrieren. Im folgenden Beispiel sei wieder LISTE1 = (A B C) mit A=5 , B=3 , C=2 : (CONS 'TIMES LISTE1)
•
(TIMES A B
(EVAL(CONS 'TIMES LISTE 1 ) )
30
Mit der CONS-Funktion wird eine neue LISP-Zelle erzeugt Das obere Beispiel als Zeiger-Diagramm dargestellt: 1 1 1
LISTE 1
- m — - m — - n a
*
»
TIMES
A
»
B
C
Ist das zweite Argument von CONS keine Liste, sondern ein Atom, so wird das entstehende Gebilde
"dotted-pair"
(Punkt-Paar) genannt, z.B.: (CONS 'A 'Z)
-»•
(A . Z)
als Zeiger-Diagramm:
T? A Z
wobei:
(CAR
1
(A . Z))
•*•
A
(CDR
1
(A . Z))
•
Z
1.1. h
17
Listen können auch in "dot"-Schreibweise
dargestellt
werden, z.B.: (ABC)
=
(A . (B . (C . NIL)))
Es gibt auch höhere Funktionen zur Listenverarbeitung *) , z.B.: (REVERSE '(A B C))
(c B A )
(SORT »(5 2 k 1 3))
(12
(REMOVE
(A C )
'B *(A B C))
(SUBST 'A 'B (UNION
(A A C)
'(ABC))
'(ABC)
3^5)
(A B C D)
'(BCD))
(INTERSECTION
'(A B C ) '(B C D))
(B C)
(NTH ' ( A B C )
2)
(B C )
(LAST '(A B C ) )
(c)
(PACK '(A B C))
ABC
(UNPACK
(A B C)
'ABC)
1.1.5 Property-Listen In LXSP können bestimmte Eigenschaften eines Atoms auf einer "Property-Liste"
(Eigenschafts-Liste)
gespeichert
und bei Bedarf abgerufen werden. Beispielsweise haben Bauklötze eine Farbe (rot, blau,
...),
sind von einem bestimmten Typ (Block, Pyramide, Kugel
,..),
von bestimmter Größe. stehen auf einem bestimmten Platz im dreidimensionalen Koordinatensystem, usw. Eigenschaften werden abgespeichert mit Hilfe der Funktion PUTPROP. Z.B. seien für den Baustein Block-D die
folgenden
Eigenschaften zu definieren: (PUTPROP
'BLOCK-D «FARBE
(PUTPROP
'BLOCK-D
'ROT)
'GROESSE '(2 2 2))
* ) siehe ggf. Kurzbeschreibungen der im Anhang A-3
Systemfunktionen
18
1.1.5
Die auf der Property-Liste abgelegten Eigenschaften können abgerufen werden mit der Funktion GETPROP . (GETPROP 'BLOCK-D «FARBE)
•
(GETPROP «BLOCK-D 'PLATZ)
Z.B.: ROT (9 k o)
Die vom LISP-System organisierte und verwaltete Eigenschaf ts-Liste besteht aus einer Reihe von Attribut-WertPaaren und hat z.B. folgendes Aussehen: BLOCK-D I H
t E H
H Z n h C D > C E > ™
FARBE
GROESSE
K X K J Z 1
PLATZ
ROT
Mit der Funktion REMPROP können Eigenschaften auch wieder gelöscht werden, z.B.: (REMPROP 'BLOCK-D
'WERKSTOFF)
H. Stoyan /St8o/ macht darauf aufmerksam, daß in PropertyListen als Eigenschaften auch Programme abgelegt werden können, die etwa die Verarbeitungsweise anderer Eigenschaften beschreiben.
1.1.6 Assoziations-Listen Assoziativ-Speicher sind mächtige organisatorische Werkzeuge. Sie werden in LISP durch "Assoziations-Listen" realisiert, die aus Punkt-Paaren folgender Form bestehen: (
(keyl
wobei keyl
. wertl)(key2 . wert2) ... (keyn . wertn) ) ... keyn (z.B. atomare) "Schlüssel". wertl
...
wertn beliebige S-Expressions sind. Es sei z.B. folgende Assoziations-Liste als Wert an das Atom ALIST gebunden:
1.1.6
19
(SETQ ALIST
•( (A . B) (X . Y) (V . W) ) )
A LI ST
\ n — ^ p — « n z i
TT
TT
f?
AB
X Y
VW
Die Funktion ASSOC liefert das zum Schlüssel keyx gehörige dotted-pair
(keyx
. wertx) der Assoziations-Liste.
Es kann wertx dann z.B. so erhalten werden: (CDR(ASSOC
'X ALIST))
Y
Als Wert kann auch hier z.B. ein Programm stehen. D. Kolb /Ko8l/ betont, daß neben komfortablen
Zugriffsmöglichkeiten
der Vorteil der Assoziations-Liste gegenüber der PropertyListe darin besteht, daß die Assoziations-Liste lokal an eine Variable
(ein Atom) gebunden werden kann, Property-
Listen dagegen stets global sind. Indikatoren von PropertyListen müssen literale Atome sein, während für die Schlüssel der Assoziations-Listen beliebige S-Expressions zugelassen sind.
1.1.7
Prädikatfunktionen
In LISP gibt es Test-Funktionen, z.B. die Funktion NULL, die feststellt, ob eine Liste leer ist. Das "Prädikat" ist ein Ergebnis, das entweder den Wahrheitswert
"wahr" oder
"falsch" hat. "Falsch" wird durch das Atom NIL,
"wahr"
durch das Atom T (true) ausgedrückt. NIL und T sind spezielle Atome, deren Werte feststehen : Sie evaluieren (wie Zahlen) auf sich selbst.
20
1.1.7
Einige Beispiele von Prädikatfunktionen im Test mit unserer LISTE 1 = (A B C) s (NULL () )
T
(NULL LISTE 1)
NIL
(ZEROP 0)
T
(AT0M(CAR LISTE1))
T
(EQUAL "A(CAR LISTE 1 ) )
T
(MEMBER 'D LISTE 1 )
NIL
(MEMBER »D '(A B C D E) )
(D E)
Die Funktion MEMBER im letzten Beispiel liefert statt T die Restliste, deren erstes Element das gesuchte toplevel Element ist. Aus Gründen einer effizienten Weiterverarbeitung gilt verallgemeinernd in LISP, daß jeder Wert ungleich NIL den Wahrheitswert "wahr" hat.
1.1.8 Die LAMBDA-Funktion Der X-Kalkül von A. Church ( 19^+1 ) wird, wie Turing-Maschine, yu. -rekursive Funktionen und ähnlichem, zur Präzisierung des Algorithmen-Begriffs verwendet. Zur Bearbeitung einer Formel, z.B. y X mit den Argumenten ( 2 , 3 ) ist es notwendig, eine Konvention bez. der Para2 3 meter-Bindung zu treffen: Gilt entweder 2 = 8 oder 3 = 9 ? X
In LISP wird in Anlehnung an die Schreibweise des
-Kalküls, womit die zuordnende Paarung der Funktions-
parameter mit den Werten der Argumentliste ausgedruckt wird
\ (
(*, y)s y x ) (2 , 3)
=9
die Funktion LAMBDA benutzt, um eine (nicht explizit benannte) Funktionsdefinition zu formulieren. . 2 Beispielsweise sei das Volumen V = TT r h zu berechnen mit
r = 1 ,
h = 2 :
eines Zylinders
1.1.8
21
( < LAMBDA ( R H ) ( TIMES
3.1 16
RR
H)>
1 2 )
V
TV
Parameter X
Funktionsdefinition
- Expression
Argumente *
6.283199
Die mit der LAMBDA-Funktion "gebundenen" Parameter haben nur "lokale" Bedeutung. Gleichnamige Atome außerhalb der LAMBDA-Funktion werden dadurch nicht angesprochen.
1.1.9 Definitionen benannter Funktionen Wird eine vom Benutzer definierte Funktion häufiger benötigt,
ist
es
zweckmäßig , ihr einen Namen zu geben ,
um sie dann wie jede andere Funktion aufrufen zu können. Diesen Wunsch erfüllt die Funktion DE (define). Angenommen, wir wollen unsere Funktionsdefinition von oben unter dem Namen ZYLINDER aufrufen, so schreiben wir: (DE ZYLINDER(R H) (TIMES
3.1^16
RR
H >
Man beachte den analogen Aufbau zur LAMBDA-Expression ! Damit ist die Funktion ZYLINDER definiert und wir können sie benutzen, z.B.: (ZYLINDER 1 2 )
6.283199
Wir haben gesehen, daß es in LISP Funktionen gibt, die beliebig viele Argumente akzeptieren (wie z.B. TIMES ). In
INTERLISP
ist
es
( trotz Definition ) wird
dann
automatisch
auch kein NIL
gestattet , Argument
zu
einer
Funktion
übergeben . Es
eingesetzt . Es gibt weiter-
hin Funktionen, die ihre Argumente nicht evaluieren (z.B. QUOTE). Selbstverständlich können auch vom Benutzer de-
22
1.1.9
finierte Funktionen mit allen diesen Eigenschaften entworfen werden. Zusätzlich besteht die Möglichkeit, Funktionen vom INTERLISP-System compilieren zu lassen, um deren Laufzeit zu verringern.
1.1.10 Eine Steueranweisung Im allgemeinen ist die Abarbeitung einer Funktionsdefinition an Bedingungen geknüpft. Die Funktion COND (condition) testet eine Reihe von Klauseln. Jede Klausel besteht aus einer Liste, deren erstes Element ein Prädikat ist und deren folgende Elemente beliebige S-Expressions sind. Diese Steueranweisung hat dann folgende Form: < COND ( prädl expr11 expr12 ... )
=
Klausel 1
( präd2 expr21 expr22 ... )
=
Klausel 2
( prädn exprnl exprn2 ... ) ^
=
Klausel n
Die Steueranweisung hat folgende Wirkung: Es wird nacheinander jedes Prädikat getestet, bis ein Prädikat zu ungleich NIL evaluiert (z.B. präd2 in Klausel 2). Dann werden nacheinander die zu dieser Klausel gehörenden S-Expressions (hier expr21 ... expr2m) abgearbeitet und anschließend die COND-Funktion (hier mit dem Wert von expr2m) verlassen. Evaluiert kein Prädikat zu ungleich NIL, so "fällt COND durch" und hat den Wert NIL. Es ist meistens sinnvoll, bei mehreren Klauseln als letztes Prädikat (prädn) das Atom T zu schreiben (dieses evaluiert wieder zu T, also ungleich NIL), um so einen definierten Ausgang anzugeben. Eine Klausel darf auch nur das Prädikat enthalten. In den folgenden beiden Abschnitten werden wir Anwendungsfälle kennenlernen.
23 1.1.11 Rekursive Funktionsdefinitionen Die Mächtigkeit und Eleganz einer rekursiven Funktionsdefinition liegt in der Reduzierung des komplexen Problems auf den einfachsten Fall dieses Problems. Wir wollen zuerst das Standardbeispiel einer rekursiven Definition, die Fakultät, programmieren: n! = n * (n-1)!
für
n £ 0
mit
0! = 1
per def.
< DE FAKULTAET(N) (COND ((ZEROP N) 1) (T (TIMES N (FAKULTAET (SUB1 N ) > In der ersten Klausel der Steueranweisung COND ist die Endbedingung programmiert (für n = 0 ist definitionsgemäß das Ergebnis gleich 1); in der letzten Klausel ist der Rekursionsschritt formuliert. Der Aufruf ergibt z.B. s (FAKULTAET 6)
720
Die Abarbeitung rekursiv definierter Funktionen geschieht über eine Stack-Verwaltung, die das bei jedem Rekursionsschritt noch offene Zwischenergebnis in einem Stack (= Stapel- oder KellerSpeicher) ablegt. Der Stack wird bis zum Rekursionsende aufgebaut und anschließend durch die nun mögliche Verknüpfung dieser Zwischenergebnisse gemäß der Funktionsdefinition wieder abgebaut. Das Ergebnis ist der Wert der Funktion. Z.B.: (FAKULTAET 2)J -v = (TIMES 2 1(FAKULTAET 1)) V ' = (TIMES 1 (FAKULTAET 0)) ' v = 2
•
2
Der Wert rekursiver Definition läßt sich noch deutlicher an Funktionen zeigen, die auf S-Expressions unbekannter Länge und Tiefe arbeiten. Angenommen, wir wollen eine Prädikatfunktion INSIDE definieren, die uns das Vorhandensein z.B. des Atoms E irgendwo innerhalb einer Liste anzeigt, z.B.:
2b
1.1.11 (INSIDE 'E *(A(X Y)(D(E F)G)H) )
•
T
Dann programmieren wir: < DE INSIDE(A L) (COND ((ATOM L)(EQUAL A L)) ((INSIDE A (CAR L) ) T) (T (INSIDE A (CDR L) > Die erste Klausel testet den einfachsten Fall, daß L ein Atom ist. Wenn ja (was auch für die Endbedingung der leeren Liste () s NIL zutrifft l), wird die S-Expression der ersten Klausel bearbeitet: Der Wert von INSIDE ist dann gleich dem Prädikat des Tests von EQUAL. Wenn nicht, dann wird als Prädikat in der zweiten Klausel INSIDE rekursiv für den CAR von L (das ist entweder ein Atom oder eine Subllste) aufgerufen. Ist das Ergebnis "wahr", so wird die S-Expression T bearbeitet, die wiederum zu T als Wert der Funktion evaluiert. Wenn nicht, dann wird in der letzten Klausel (wegen des T Prädikats ) INSIDE rekursiv für den CDR von L (also die um das erste Element reduzierte Liste bzw. Subliste) aufgerufen. Wie man sieht, wird damit eine Baum-Struktur in allen ihren Verzweigungen durchsucht.
1.1.12 Iterative Funktionsdefinitionen Es gibt Probleme, die ihrer Natur nach effektiver iterativ (statt rekursiv) zu lösen sind. Darum stellt LISP eine Funktion PROG zur Verfügung, die es erlaubt "Programme" iterativ zu formulieren, ähnlich wie in FORTRAN, mit Entscheidungen, Sprung-Befehlen auf Marken, Return usw. Als Beispiel sei die Fakultätsfunktion als PROG definiert. Auf die im PROG-Rumpf benötigte, lokal gebundene Hilfsvariable RESULT wird schließlich das Ergebnis gesetzt, was mit RETURN übergeben wird. Das COND besteht hier nur aus einer Klausel. Der Rest ist selbsterklärend :
1.1.12
25
< DE FAKULTAET(N) (PROG (RESULT) (SETQ RESULT 1) LOOP (COND ((ZEROP N)(RETURN RESULT))) (SETQ RESULT (TIMES RESULT N)) (SETQ N (SUB1 N)) (GO LOOP) > Der Aufruf erfolgt wie oben : (FAKULTAET 3)
•
6
Man vergleiche diese Definitionsgleichung mit der rekursiven aus dem vorigen Abschnitt !
1.1.13 MAP-Funktionen Ist z.B. mit jedem top-level Element einer Liste die gleiche Operation auszuführen, so müßte ein Programm mit Kontroll-Struktur geschrieben werden, was die Listenelemente nacheinander (als CARs der Restlisten) der Operationsfuriktion übergibt, so lange, bis die Liste abgearbeitet ist. Die in LISP verfügbaren MAP-Funktionen befreien den Programmierer vom Schreiben entsprechender Kontroll-Strukturen. Betrachten wir zwei Beispiele: Der Funktion MAPCAR wird als erstes Argument eine Liste übergeben. Mit dem zweiten Argument wird die Operationsfunktion angegeben, die hier die CARs der Sublisten aussondert : (MAPCAR «((A X)(B Y Z)(C)) *CAR)
.+.
(A B C)
Als weiteres Beispiel einer MAP-Funktion, die über zwei Listen arbeitet
(l. und 2. Argument) sei MAP2CAR genannt.
Die Operationsfunktion
(als 3. Argument), hier CONS, ver-
knüpft paarweise die Listenelemente zu dotted-pairs:
26
1.1.13 (MAP2CAR '(ONE TWO THREE) '(1 2 3) 'CONS) ((ONE . 1)(TW0 . 2) (THREE . 3))
Abschließend sei in diesem Zusammenhang angemerkt, daß manche Funktionen (wie z.B. PLUS und TIMES) in der Anwendungsphase ihre Argumente einzeln und nicht als Liste erwarten. Liegt aber eine Datenliste vor, so sorgt die Funktion APPLY für eine korrekte Steuerung der ArgumentÜbergabe, z.B.: (SETQ L1
'(532))
(APPLY 'TIMES L1)
30
1.1.14 Beispiele zur Semantik in LISP In der Einleitung wurde gesagt, daß das Erlernen von LISP durch eine einfache Syntax erleichtert wird. Bei der Vielzahl der verfügbaren Systemfunktionen (280 in /Ep79/) und dem Nuancenreichtum ihrer Semantik ist jedoch ein Vergleich mit einer natürlichen Sprache naheliegend : Vom "Kennen" zum "Können" ist ein Weg harter Übung zu bewältigen ! Beispielsweise werden mit den folgenden Funktionen Listen erzeugt, jedoch mit unterschiedlicher Wirkung: (CONS 'a 'l) fügt a als erstes top-level Element in die Liste 1, z.B.: (CONS 'A •(B) )
»
(A B)
(CONS '(A) «(B) )
•
((A) B)
(CONS '(A X) '((B Y)) )
•
((A X)(B Y))
(LIST 'a 'b ... ) erzeugt eine Liste, deren top-level Elemente a, b, ... sind, z.B.: (LIST »A 'B)
•
(A B)
(LIST '(A) >B)
•
((A) B)
(LIST '(A X) '(B Y) )
((A X)(B Y))
27
1.1.14 (APPEND
,
1 1 '1 2 ... ) erzeugt eine Liste, deren top-level
Elemente die top-level Elemente der Listen 1^, 1^, ... sind , z . B. s (APPEND ' (A) '(B) )
-
(A
(APPEND "((A)) '(B) )
•
((A)
(APPEND '((A X)) ' ( ( B Y ) ) )
-
B) B)
( ( A X ) ( B Y ) )
Die Funktionen CONS, LIST und APPEND erzeugen als Ergebnis neue Listen, ohne die Listen der Argumente zu verändern. Andererseits gibt es Funktionen (z.B. NCONC, RPLACA, RPLACD), die keine neuen Listen erzeugen, sondern vorhandene Strukturen modifizieren.
1.1.15 LISP-Dialekte und Literaturhinweise Ein die LXSP-Literatur studierender Anfänger ist verwirrt durch das Vorhandensein vieler LISP-"Dialekte". Nach der ersten LISP-Version von 1959 wurden zahlreiche Verbesserungen vorgenommen und von McCarthy et al als "LISP 1.5 Programmer 1 s Manual" 1962 publiziert. LISP 1.5 ist ein sog. "EVALQUOTE-LISP". Die top-level Funktionen werden z.B. so eingegeben: CONS(A
B)
*
(A . B)
Der 1967 herausgegebene "LISP 1 .5 Primer" von C. Weissman /We67/ war das erste LISP-Lehrbuch. Die starke Betonung der "dot"Notation ist nicht mehr zeitgemäß. Wegen zahlreicher Lö— sungsbeispiele zu den Übungsaufgaben ist das Buch auch für das Selbststudium geeignet und noch immer empfehlenswert für diejenigen, die mit "EVALQUOTE"-Dialekten arbeiten müssen. Der hier in den Beispielen benutzte moderne Dialekt ist ein sog. "EVAL-LISP". In dem 1976 erschienenen, didaktisch
28
1.1.15
sehr gut aufgebauten und humorvollen Lehrbuch von Sikl6ssy /Si76/ "Let's Talk LISP" werden beide Dialekte parallel behandelt.
In
dem
1981
erschienenem Lehrbuch
"LISP"
von
Winston + Horn /WH81/ ist MACLISP (ein "EVAL-LISP")
die
Sprachgrundlage. Es ist ein Arbeitsbuch für Anfänger und Fortgeschrittene mit zahlreichen Lösungsbeispielen für allgemein nützliche Programme und mit umfangreichen Beispiel-Problemen aus dem AI-Bereich. Die vierteilige LISP-Serie von D.R. H o f s t a d t e r / H 0 8 3 /
(aus
dem Scientific American übersetzt von C.-M. Hamann) ist als unterhaltsame Einführung und ideale Ergänzung zu unserem Text sehr zu empfehlen. "Es gibt keine LISP-Standardisierung. Das Problem der Dialekte existiert, da praktisch jede LISP-Benutzergruppe ihre eigenen Modifikationen an der Sprache und am System vorgenommen hat." (Sammet /Sa69/)
Einen Überblick über
LISP-Dialekte als wertvolle Hintergrundinformation
(mit
Literaturangaben) sowie orientierenden Hinweisen auf Sprachen, die auf LISP aufbauen (wie z.B. PLANNER und CONNIVER) , ist bei Stoyan / S t 8 o /
zu finden. Zusätzliche Informationen
(auch über andere AI-Sprachen) sind im AI-Handbook /AI82/, Vol.II , Ch.VI enthalten. Das 1974 von W. Teitelman vorgestellte INTERLISP wurde insbesondere unter dem Aspekt der Interaktivität (daher der Name) entwickelt. "Es gilt gegenwärtig als die beste interaktive LISP-Implementation
... und ist ohne Zweifel
das für Zwecke der Künstlichen Intelligenz wichtigste und umfassenste System " (Stoyan /St8o/) . INTERLISP schafft eine den Programmierer außerordentlich unterstützende
System-
umgebung. Beispielsweise fängt das System durch eine "Do-What-I-Mean"
(DWIM) -Fähigkeit eine Vielzahl auftre-
tender Fehler automatisch ab, ohne dabei den Programmablauf abzubrechen. In Deutschland wurde INTERLISP von
2
1.1.15
9
Siemens übernommen und ist an mindestens 9 Institutionen (nach /Ep79/) auf Siemens-Anlagen unter dem Betriebssystem BS 2000 installiert. Das sehr ausführliche "SIEMENS—INTERLISP
Benutzerhandbuch"
von Kolb /KO81/ ist nicht als Lehrbuch, sondern als Nachschlagewerk konzipiert. Demgegenüber wendet sich das "INTERLISP-Programmierhandbuch" von B. Epp /Ep79/ "sowohl an den Neuling wie an den in LISP Erfahrenen und will so Einführung und Arbeitsunterlage zugleich sein". Programmierhandbücher können aber mit einfachen Beispielen nur einen ersten Eindruck in LISP vermitteln. Die Mächtigkeit der Sprache erschließt sich erst bei der Lösung komplexer Aufgaben. Winston /Wn77/ empfiehlt daher: "Die beste Art, LISP zu lernen, ist tapfer hineinzuspringen, mitten in ein interessantes Programm." Ein solches Beispiel (die Implementierung einer "Block-Welt") wird hier in diesem Lehrbuch ausführlich behandelt. Der folgende Abschnitt gibt dazu eine kurze Einführung.
1.1.16 Demonstration eines Übungsbeispiels T. Winograd /Wd72/ hat 1971 mit seinem SHRDLU-Programm einen "Markstein" der AI-Forschung gesetzt: Ein einarmiger Roboter kann in einer
(simulierter)
"Bauklötzchen-Welt"
manipulieren. Er führt einen (schriftlichen) Dialog in natürlichem Englisch. Er reagiert auf Befehle mit Aktionen, die eine komplexe Handlungskette erfordern, beantwortet Fragen, speichert Informationen, erinnert sich, diskutiert Pläne und kann sie ausführen. Das Programm enthält einen "allgemeinen Problemloser" (¿eneral jsroblem solver, GPS), eine englische Grammatik, einen Parser, führt die semantische Analyse durch und "versteht, wovon die Rede ist".
1.1.16
30
(SITUATION) SITUATION
BLOCK-A
BLOCK-B
BLOCK-C
INDICATOR
VALUE
26-SEP-80
10:50:51
SUPPORTED-BY DIRECTLY-SUPPORTS PLACE SIZE TYPE COLOR SUPPORTP
BLOCK-B NIL (1 1 2) (2 2 2) BLOCK GREEN T
TABLE (BLOCK-A) (1 1 0) (2 2 2) BLOCK RED T
TABLE NIL (6 1 0) (2 2 2) BLOCK BLUE T
BOX DIRECTLY-SUPPORTS
PLACE NIL
TABLE DIRECTLY-SUPPORTS
P L A C E (5 (BLOCK-B
HAND G R A S P I N G HAND P O S I T I O N
NIL (2 5
(8
7)
8 0)
5 0) BLOCK-C
SIZE
SIZE BLOCK-D
BLOCK-D
SPHERE
PYRAMID
TABLE NIL ( 9 It 0 ) (2 2 2) BLOCK RED T
TABLE NIL (It 3 0 ) (2 2 2 ) SPHERE GREEN NIL
TABLE NIL (3 8 0) (2 2 2) PYRAMID RED NIL
(I» >1 0 . 1 0 0 0 0 0 )
COLOR
BLUE
( 1 0 10 SPHERE
COLOR BOX)
BLACK
0) PYRAMID
1.1.16
31
(SITUATION) SITUATION
BLOCK-D
BLOCK-A
BLOCK-B
BLOCK-C
INDICATOR
VALUE
26-SEP-80
11:02:07
SUPPORTED-BY DIRECTLY-SUPPORTS PLACE SIZE TYPE COLOR SUPPORTP
TABLE (BLOCK-B) (1 9 0) (2 2 2 ) BLOCK GREEN T
BLOCK-A BLOCK-B BLOCK-C (BLOCK-C) (BLOCK-D) (SPHERE) (1 9 2) ( 1 9 l|) ( 1 9 6 ) (2 2 2 ) (2 2 2 ) (2 2 2 ) BLOCK BLOCK BLOCK RED RED BLUE T T T
BOX DIRECTLY-SUPPORTS
PLACE (5 5 0 ) (PYRAMID)
SIZE
TABLE DIRECTLY-SUPPORTS
PLACE ( 5 5 0 ) (BOX B L O C K - A )
S I Z E ( 1 0 10 0 )
mmmmmmmmmmmmmmmmmm
HAND G R A S P I N G HAND P O S I T I O N
mmmmmmmmmmm
NIL (5 5 2 . 0 9 9 9 9 9 )
« • • • • • • • • a
(U 0 . 1 0 0 0 0 0 )
SPHERE
PYRAMID
••«•••saaaa
BLOCK-D NIL (1 9 8) (2 2 2 ) SPHERE GREEN NIL
BOX NIL (5 5 0 . 1 (2 2 2 ) PYRAMID RED NIL
COLOR B LUE COLOR BLACK
1.1.16
32
(PUT-ON ' B L O C K - A "O.K."
SITUATION
'BOX
)
2
( SITUATION) SITUATION
BLOCK-A
BLOCK-B
BLOCK-C
BLOCK-D
SPHERE
PYRAMID
• a a B S B a a a B B B B B B a a B B B a B B B B a a a B B B a a B B a a N a a R B e a a s B s s s B B B s s s s B a
INDICATOR
VALUE
SUPPORTED-BY DIRECTLY-SUPPORTS PLACE
TABLE NIL
TABLE NIL
TABLE NIL
TABLE NIL
SIZE TYPE COLOR SUPPORTP
TABLE BOX NIL NIL (It 5 0 . 1 0 0 0 0 0 ) (4 1 0 ) (2 2 2 ) (2 2 2 ) BLOCK BLOCK GREEN RED T T
(8 9 0 ) (2 2 2 ) BLOCK BLUE T
(8 6 0 ) (2 2 2 ) BLOCK RED T
(6 1 O) (2 2 2) SPHERE GREEN NIL
(9 2 0 ) (2 2 2) PYRAMID RED NIL
BOX DIRECTLY-SUPPORTS
PLACE (5 5 0 ) (BLOCK-A)
SIZE
TABLE DIRECTLY-SUPPORTS
PLACE (5 5 0 ) S I Z E ( 1 0 10 0 ) COLOR ( B L O C K - B B L O C K - C B L O C K - D SPHERE PYRAMID BOX)
HAND G R A S P I N G HAND P O S I T I O N
NIL (it 5 2 . 0 9 9 9 9 9 )
26-SEP-80
11:07:02
( ( IN) (DIFFERENCE (TIMES (SUBÌ ALPHA) BETA) (PLUS ALPHA BETAG A M M A ) 24 OUT ) (OUT) 11»(OUT ) ;
)
(IN) (CUT) ( 0 u1) ÌOUT) III') Cji.'T)
(• 6 ó 15-
(ji'ri n i n i ( ri) (UI'Tl
lè-
'."'l'I ¡w.i t i U-'l (3MT! (GUT) Cl'Jl ) (IN) (OHI) (ODI) (OI'T) (IN) ( OUT ) (OLn) (OHT ) (IN) (OUT) (OUT) Ì C II T ) (IN) (OUT) (CUT) (CUT) (IN) (OUT) (OUT)
*)
ISETQ 56
TSTi
(SETQQ (TIMES
(TIMES
TST2 (TIMES ALPHA BETA!
ALPHA
ALPHA
17" IEVAL 56 18(* 7 7 19-
TST2 )
»)
(CAR TST2) TIMES 2.0(CDR TST2) (ALPHA BETA) 11(CAADR BETA 22(» 8
8
LISI)
»)
2 5 -
(OUT)
(IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) COUT) (IN)
(C AR ' ( A L P HA ALPHA 2lf-
.
BETA)
)
(CDR BETA 25-
.
BETA)
)
(J
K>>)
(* 9 9 Z b -
(OUT)
(CAR A
( C U I )
17-
'(ALPHA
*)
TREE)
(OUT)
(IN) (OUT) (OUT)
(CADR ( B CD
TREE) (H I ) )
(E
18-
(OUT) «ItO (OUT) (OUT) (OUT)
(CADDR TREE) ( t ( F ( L M ) ) ( G ( N O ) ) ) 29-
BETA)
BETA)
)
)
.2.2
(IN) (OUT)
(• 10
(OUT) (OUT) (IN) (Ol'T) (OUT) (OUT) (IN) (OUT) (OL'T) (OIIT ) (IN) (OUT) (OUT) (Ol'T) (IK) (OUT) (OL'T) (Ol'T)
30-
10
*)
(CAR(CDADAR(CDDADR K 31(CAADAR(COADDR L 32( • 11 11 33-
TREE>
TREE>
»)
(CONS T S T 2 LIS?) ( ( T I M E S ALPHA B E T A ) 341
(CUT) (OUT) (OUT) (IN) (CUT) (OUT ) (OUT) (IN) (OUT ) (OUT) (OUT) ( IN) (OUT ) (OUT) (OUT)
'NET)
14
51,(SETQ
ZIFF
(DREI
.
. .
((NULL
'((NULL
.
THREE)(VIER
(SIEBEN (OUT)
'NET)
ZERO) FOUR)
(ACHT 55-
EIGHT)
.
ONEXZWEI
.
. NINE)) ) . TWO) (OR E I .
(EINS
.
ONE)
(FUENF
.
FIVE)
(NEUN
.
(ZWEI
(SECHS .
NINE))
'NULL
ZIFF)
)
(CDR NINE
(ASSOC
'NEUN
ZIFF)
>
5715
58" •ALPHA)
(NULL T (.0-
()
(NULL T (,1 -
NIL)
(ATOM T
•ALPHA)
)
hl(ATOM T
(EQUAL T tv-
()
)
(CAOAOR
LISI)
.
SIX)
E I G H T ) (NEUN
(ASSOC
(NULL NIL 59-
TWO)
.
(CD R ZERO 5G-
(• 15
.
FIVE)(SECHS
FOUR) ( FUENF
S E V E N ) (ACHT
(VI E R . .
ZERO) ( E I N S .
(CADR
LIS2)
>
SIX)
THREE)
(SIEBEN
.
SEVEN)
1.2.2
(IN) ( OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT ) (OUT) ( IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (CUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (CUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) ( IN) (OUT) (OUT) (OUT)
(EQUAL N IL l>5-
(CAR
(MEHBER NIL 44-
LIS1)
'BETA
(CAR
LIS2)
)
US?)
(MENBER 'GAMMA LIS2) (GAHMA (DELTA E P S I L O N ) ) w(»
16
68( (LAMBDA(A B X C O N S (BETA . A L P H A )
B A))
'ALPHA
'BETA )
t 9 -
(« 1 7 « ) 17 70(SETQ 2 71-
W
2)
(S ETQ 3 72-
X
3)
(SETQ 4 73-
Y
4)
(SET8 5 74-
I
5)
(DE T E S T ( X ) ( S E T i TEST 75" (TEST 8 76W 2 77X 3 78T 4 7Î"
z 8 80-
U)
* (TIMES
X Y))(SETQ
Z
x>>
50
1.2.
(IN) (OUT) (OUT) (OUT) (IN)
( • 18 18 81(0E
•)
LEFTCL)(APPEND(CDR
L)(LIST(CAft
(OUT) (OUT) (OUT)
LEFT 62-
(IN) (OUT) (OUT) (OIIT)
(LEFT (BETA 85-
'(ALPHA BETA SAHNA ALPHA)
GAHMA)
)
"(BETA
GAMMA
ALPHA)
)
ALPHA
BETA)
(IN)
(LEFT
(OUt) (OUT ) (OUT)
(GAMMA 8V-
(IN) (3IJT) (OUT)
( * 19 19 85-
(IN) (U'JT) (OUT) «OUT) 1 I-T»
(DE F A C E ( F ) FACE 86-
cauri
(FACE
*>
(QUOTIENT
(TIMES
(DIFFERENCE
-40)
-40,000000
(OUT) < U;IT I
87"
(IN) OUT) (OUT) (OUT )
(FACE 0) '17.777771 88-
«l'I»
(FACE
(U'JT) (J'.IT) I DUT )
37.777771 89-
(IN)
(•
(OUT)
20
(OUT)
L)>
20
100)
O
90-
(OUT) (IN)
(DE
STRUCEQ(SEX1
SEX2)
(COND
(OUT) (OUT) ( OUT) (IN) (OUT) (OUT) (OUT) (IN)
((ATOM SEX1) (ATOM S E X 2 ) ) ((ATOM SEX2) NIL) ((STRUCEQ (CAR SEX 1) ( C A R SEX 2 ) ) ( S T R U C E O (CDR SEX1) (CDR SEX2))) (T NIL)> STRUCEQ 91 (STRUCEO
'(ALPHA
BETA)
'((ALPHA)
BETA)
(STRUCE«
'(L1SP(IS(VERY))BEAUTIFUL) •(NUR(FLIEGEN(IST))SCHOENER)
(OUT) (OUT)
)
NIL 11-
T 95-
>
F
32.)
5.)
9.>
1.2.2
51
(IN) (OUT) (OUT) (OUT) ( IN)
(• 21 21
(OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT ) ( IN)
REVERSALL 95-
(OUT) (OUT) (OUT) (IN)
(OUT) (OUT) (OUT) ( IM (OUT) OUT) (DIJT) € IM) (O'JT) (OUT) (OUT) (IM) (OUT) (OUT) OUT) (IN) (OUT) (O'JT) (OUT) (IN) (OUT) (OUT) (OUT) I IN) ( OUT ) ( JUT ) (OUT)
(DE
•)
REVERSALKSEX) (COND ( (ATOM SEX) SEX) (T ( A P P E N D ( R E V E R S A L L ( C D R S E X ) ) (LIST «REVERSALL (CAR
( R E V E R S A L L '(ALPHA (BETA ((GAMMA BETA) ALPHA)
(• 22 22
GAHMA))
SEX)>
)
•)
17-
(DE REMOVAL1(SEX1 SEX2) (COND ((ATOM SEX2) (COND ( ( E Q U A L S E X 1 S EX 2 ) NIL) CT S EX 2)) ) ( ( E Q U A L SEX1 (CAR SEX2)> ( R E M O V A L 1 SEX1 (CDR SE X2))) (T ( C O N S (REM O V A L 1 S E X 1 (CAR S E X 2 ) ) ( R E M O V A L 1 S EX 1 « C D R S E X Z ) > REHOVAL1 98(DE
REMOVALL«SEX 1 SEX2) (COND ( ( E Q U A L SEX1 S E X 2 ) NIL) (T ( R E M O V A L 1 S E X 1 S E X 2 ) > REMOVALL 99" (REMOVAL1 (EPSILON) 100-
I(EPSILON)
(REMOVALL NIL 1-
'ALPHA
(REMOVALL NIL
'(BETA)
'(EPSILON)
'ALPHA)
'(BETA)
)
l-
( R E M O V A L L 'BETA LISI) (ALPHA (GAMMA) DELTA) 3(REMOVALL '(GAMMA) LISI) (ALPHA (BETA GAMMA) DELTA)
(BETA GAMMA)) )
(DE
LENGTH-TEST-I(L) (PROG (ft ) (SETS N 0) LOO P( CO ND ((NULL L) (RETURN N) ) ) ( S ETQ N (ADD1 N)> (SETQ L (CDR L)) (GO L O O P ) > L ENGTH-TE S T-I 9(LENGTH-TEST-I 3 10-
LIS1)
(• 24 • ) 24 11(DE Q U A O ( L ) ( M A P C A R Q UA D 12-
L '(LAMBDA(X)(TIMES
(QUAD > ( 0 1 2 3 4 ) ) ( 0 1 4 9 16) 1J(• 25 *) 25 1V(APPLY 25 15-
'PLUS
(DATE) " 7-JUN-81
(EXIT)
(QUAD
'(3 4 ) ) )
02:47:45"
X X)) >
222222222
22222222222 22222222222 22222 22222 22222 222222 222222 222222
222222 22222 22222222222 22222222222 22222222222
I N H A L T 2.1
Beispiele zur Definition von Funktionen
55
2.1.1 Funktionsdefinitionen MAX MIN
55 GROESSERP KLEINERP
Funktionen, die ihre Argumente evaluieren
(LAMBDA-Typ)
mit festgelegter Anzahl von Argumenten (spread) mit beliebig vielen Argumenten (no-spread) Funktionen, die ihre Argumente nicht evaluieren (NLAMBDA) mit festgelegter Anzahl von Argumenten (spread) mit beliebig vielen Argumenten (no-spread) 2.1.2 Speicher - ¿ RUcklade - Prozeduren_in_INTERLISP
70
Die Prozedur FILES? / Y / MAKEFILE Die Prozedur LOAD 2.2
Implementierung des Puzzles "Die Türme von Hanoi"
73
Erklärung des Puzzles COUNT-TOH Funktionen zur "regelrechten" Simulation des Puzzles . RESET-TOH mit COUNTDOWN , COUNTUP TOWER—OF-HANOI mit TRANSFER-TOH , MOVEDISK-TOH 2.3
8
Übungsaufgaben Mengen-Operationen Infix-Präfix / Präfix-Infix
Transformationen
Symbolische Differentiation eines Polynoms Bau eines "Experten-Systems" aus einer Regel-Basis
3
5h M E R K B L A T T
zum
2. Kapitel
Das Puzzle "Die Türme von Hanoi" Spiel-Beschreibung Das Spiel besteht aus einer Grundplatte mit drei senkrechten Stiften (A, B, C ) sowie aus einer beliebigen Anzahl ( > 0 ) von Scheiben (z.B. 1, 2, 3,
unter-
schiedlicher Größe mit einer zentrischen Bohrung, In der Start-Situation des Spieles sind alle Scheiben so auf Stift A aufgereiht, daß immer eine kleinere Scheibe auf einer größeren liegt. Ziel des Spieles ist es, mit der geringsten Anzahl von Schritten den Turm von Stift A nach Stift C zu bringen. Unter Zuhilfenahme eines Zwischenlagers bei Stift B darf mit Jedem Zug nur eine Scheibe bewegt werden und zwar nur so, daß stets eine kleinere auf einer größeren Scheibe liegt.
A
B
C
A
StQf t
B
C
Eiel
A
B
C
" Zwischen-Zit.1 "
Der "Trick*1 des Puzzles besteht in der rekursiven Lösung des Problems 1. Schritt J Versetze den Stapel (n-t) vom Start- auf das Zwischenlager. 2. Schritt t
Versetze die nun frei liegende Scheibe n vom Start- zum Ziel-Stift.
3. Schritt t
Versetze den Stapel (n-l) vom Zwischenlager zum Ziel-Stift.
Historie Die Sage erzählt, daß Mönche in einem Kloster bei Hanoi an dieser Aufgabe mit 6k
Scheiben arbeiten, yenn sie diese gelöst haben werden, so wird gesagt, sei
"das Ende aller Dinge"
erreicht.
Aufgabe Schreiben Sie eine Funktion COUNT-TOH, die die minimale Anzahl von Zügen für eine gegebene Stapelgröße n berechnet. Unter der Annahme, daß Je Sekunde ein Zug erfolgt, berechnen Sie, wie lange es mindestens dauern würde, bis ein Turm mit 31 Scheiben versetzt ist ! Schreiben Sie ein Programm-System, das dieses Spiel "regelrecht"
simuliert.
55 2.1 Beispiele zur Definition von Funktionen
2.1.1 Funktionsdefinitionen Charakteristisch für LISP ist das Schreiben von Funktionen mit gewünschten Eigenschaften. Wir wollen das Wissen aus der "Einf. Übersicht" hier systematisch vertiefen. Man unterscheidet Funktionen, die ihre Argumente vor Eintritt in den Funktionskörper evaluieren (Funktionen vom LAMBDA Typ) bzw. nicht evaluieren (NLAMBDA). Weiterhin unterscheidet man Funktionen, die eine festgelegte Anzahl von Argumenten erwarten (spread Typ) bzw. eine beliebige Anzahl von Argumenten akzeptieren (nospread). Der Funktionstyp wird durch den Modus der Definition festgelegt. 2
Beginnen wir mit der Definition einer Funktion vom spread-LAMBDA Typ: MAX soll aus einer Liste mit Zahlen den größten Wert ermitteln. Die Definition einer Funktion vom LAMBDA Typ erfolgt mit Hilfe der Systemfunktion DE (define). die dem Funktionsnamen (einem literalen Atom, hier MAX) die Funktionsdefinition zuordnet. Nach dem Funktionsnamen folgen die
(Eingangs-Parame-
ter. Beim spread Typ werden sie in einem Klammer-Paar eingeschlossen. Arbeitet die Funktion ohne Parameter, so muß das leere Klammer-Paar oder NIL geschrieben werden! Für MAX ist nur ein einziger Parameter, die Liste L der numerischen Atome, festzulegen. Die weitere Besprechung zur Definition des Funktionsrumpfes ist in der hier vorliegenden Eingabeform unübersichtlich. Vom INTERLISP wird darum eine "prettyprint"-Funktion PP zur Verfügung gestellt, die eine strukturierte Darstellung der Funktionsdefinition erzeugt .
2.1.1
56
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OU1) (OUT) ( IN) (0IIT) (OUT) (OUT) (IN)
»0 X
KIP.LISP P 5 0 0 LOADING SIEHENS-INTERLISP
• « • • » 600»
(OUT) (OUT) (IN) (OUT) (OUT) (OUT)
VERSION
4.0
• " < • •
AFTERNOON.
1 (DATE) "Z9-APR-81 Z(DE
13:33:11"
MAX(L)(PROG(X)(COND((NULL
(SET«
(OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT)
RESET
-
X(CAR
L))LOOP(SET«
LICDR
L)(RETURN
(COND ( ( N U L L
L ) (RETURN X ) ) ( ( L E S S P
(SETS
D ) ) ) (GO
X(CAR
LOOP)>
MAX 3(PP
RAX)
(GO L O O P > >
(MAX) 4(MAX NIL 5-
()
(MAX 3 6-
'(3)
(MAX 5 7(MAX S 8-
)
)
' ( 2 5 1 4 ) )
• (1
2
5 4)
)
NIL)))
L>) X(CAR
D )
2.1.1
(IN)
57
(DE
MAX
(SET«
(OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT)
L
(PROG(X)(COND
RE0EF1NED)
MAX)
> LOOP(C ET L (C ) (RE (GR E A T E R (SETS P XX (CAR(CAR L> L)) ( G O L O O P > > (MIN) 17M ( 1N NIL) NIL 18(H IN 3) 3 19(MN 2 5 1«) 1 20(APPLT B ' IN >(2 5 1 «) ) 121-
2.1.1
(IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT ) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT)
61
CDE GROESSERP(L)(COND((NULL L)T)((NULL(CPR L))T) ((GREATERP(CAR L H C A D R L))(GROESSERP(COR L)))(T NIL)> GROESSERP 22-
(PP GROESSERP) > T)
((GREATERP (CAR L) (CADR L>) (GROESSERP (CDR L))) (T N I L » (GROESSERP) 23(GROESSERP ( T NIL)> (GROESSERP GROESSERP 38(PP
REDEFINED)
GROESSERP)
) NIL) ( ( N U L L (CD R L > > T) ((NOT (NUHBERP (CADR L))> NIL) ((GREATERP (CAR L) (CADR D ) (APPLY (QUOTE GROESSERP) (CDR L))) (T N I L » (GROESSERP) 39(GROESSERP T
NIL)
4 0(GROESSERP T 41-
S)
(GROESSERP NIL 42-
1 2
3
4)
(GROESSERP T 43-
4
2
1)
(GROESSERP NIL «4-
4-3
3
'A
1)
L)))NIL)
2.1.1
(IN) (OIIT) (oin) (OUT) (OUT) (IN) (OUT ) (OUT) (Ol'T) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT)
65
(DE K L E I N E R P L (APPLY (KLEINERP REDEFINED) KLEINERP 45(KLEINERP T 46-
NIL)
(KLEINERP T 47-
5)
(KLEINERP T 48-
1 2
3
4)
(KLEINERP
1 2
4
3)
'GROESSERP
(REVERSE
L)>
NIL 49-
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(GROESSERP U.B.A. A
(IN)
(DF GROESSERP L (COND((NULL L)T)((NOT(NUMBERP(CAR ((NULL(COR L))T)((NOT(NUHBERP(CADR L)))NIL)
(OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OL'T) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT)
4
3 * 1 )
RESET
«*»«*»
50-
((GREATERP(CAR L)(CAOR ( A P P L Y ' 6 R O E S S E R P (CDR (GROESSERP REDEFINED) GROESS ERP 52(PP
L)) L)))(T
NIL)>
GROESSERP)
> (GROESSERP) 53(GROESSERP T 54-
4 3 2
1)
(GROESSERP NIL 55-
4 3 A
1)
L)))NIL)
66
2.1.1
k5 Auch KLEINERP soll als no-spread-LAMBDA Typ definiert werden. Dazu muß erstens das Klammer-Paar um den Parameter L weggelassen und zweitens (wegen des no-spread Typs von GROESSERP) die Funktion APPLY angewandt werden. Die Beispiele mit Zahlen laufen wie erwartet. h9 Nun rufen wir GROESSERP mit einem nicht-numerischen Argument A , ohne das quote zu setzen und stellen fest : INTERLISP macht einen automatischen RESET mit der Meldung "ungebundenes Atom A" (nicht aber "nicht-numerisches Argument"!). Die Erklärung ist, daß wir eine Funktion vom LAMBDA Typ geschrieben haben. Diese evaluiert ihre Argumente bevor sie dem Funktionsrumpf übergeben werden. Bei den numerischen Argumenten haben wir nichts bemerkt, da die Evaluation wieder die Zahl selbst ist. Im Beispiel 36 unterblieb die Evaluierung, da die Liste mit einem quote versehen wurde; im Beispiel k3 haben wir den gewünschten Effekt dadurch erreicht, daß wir vor das Argument A ein quote setzten! 52 Zur Übung wollen wir nun die Funktion GROESSERP so umschreiben, daß ihre Argumente nicht evaluiert, sondern im Original
dem Funktionsrumpf übergeben werden s
Eine NLAMBDA Funktion wird dadurch definiert, daß statt DE die Funktion DF (define *) auf gerufen wird. Im prettyprint erscheint NLAMBDA . Der Rest bleibt wie zuvor. 5 3 Die Beispiele zeigen, daß der gewünschte Effekt eingetreten ist: Ein nicht-numerisches Atom wird nicht evaluiert, sondern als solches erkannt i das Ergebnis ist NIL.
*) genauer : spread LAMBDA-Funktionen werden als EXPR-Typ und NLAMBDA-Funktionen als FEXPR-Typ bezeichnet. Die no-spread Typen als EXPR* bzw. FEXPR* .
2.1.1
67
Grundsätzlich gilt: Eine LISP-Funktion kann so definiert werden, daß entweder alle Argumente evaluiert werden oder keines. Mischformen (wie z.B. SETQ), die einige ihrer Argumente evaluieren, werden als NLAMBDA Typ definiert. Durch Aufruf von EVAL im Funktionsrumpf werden dann die entsprechenden Argumente evaluiert. 56 Die Funktion KLEINERP wird ebenfalls aus Übungsgründen in einen no-spread-NLAMBDA Typ umgeformt. Die Beispiele liefern die erwarteten Ergebnisse. 59 Wir kommen nun auf MAX und MIN zurück. Auch in diese Funktionen wollen wir den Test auf nicht-numerische Atome einbauen, behalten aber die no-spread-LAMBDA Version bei. 60 Die ersten drei Beispiele ergeben die erwarteten Resultate. Würden wir jetzt das Beispiel 6k sofort ausführen, so wäre ein RESET mit der Meldung "ungebundenes Atom A" wie bei
die Folge!
63 Jetzt aber binden wir mittels SETQ zuvor an A ein nicht-numerisches Atom, z.B. ein Fragezeichen. Wird nun 6k ausgeführt, so wird A evaluiert, der Wert von A ist das Fragezeichen und dieses wird dem Funktionsrumpf übergeben. Das nicht-numerische Atom wird erkannt und definitionsgemäß ist das Ergebnis NIL. 66 Wenn wir statt dessen z.B. an das Atom B einen numerischen Wert binden und Beispiel 66 ausführen, so wird B evaluiert, der Wert von B (hier 5) wird dem Funktionsrümpf übergeben und MAX berechnet. Das Ergebnis ist hier gleich dieser 5. 68 Bei der Funktionsdefinition von MIN gehen wir ebenso vor. Die Beispiele arbeiten erwartungsgemäß. Bemerkenswert ist, daß Funktionen des LAMBDA Typs einfache "Schachtelungen" ermöglichen, wie das letzte Beispiel zeigt.
2.1.1
68
(OUT) (IN) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT ) (OUT) (IN)
(OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT ) (OUT) (OUT) (OUT) (OUT) (0(I1> (OUT) (OUT) (IN) (OIIT ) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) ON) (OUT) (OUT) (OUT)
(DF K L E I N E R P I (APPLY (KLEINERP REDEFINED) KLEINERP 56(KLEINERP T 57-
12
(KLEINERP NIL 58-
1 2 A 4)
"GROESSERP
( R E V E R S E L)>
3 4)
(DE MAX L < P R O G ( X ) ( C O N D ( ( N U L L L ) ( R E T U R N N I L ) ) ) (SETQ X (C AR L ) ) ( C O N D ( ( N O T ( N U H B E R P X ) ) ( F E T U R N N I L ) ) ) LOOP (SETQ L (CDR L » ( C O N D (( NULL L X R E T U R N X)) ( ( N O T ( N U M B E R P (CAR L ) ) ) ( R E T U R N NIL)) ((LESSP X(CAR L))(SETQ X(CAR L ) ) ) ) ( 6 0 L 0 0 P ) > (MAX MAX 59(PP
REDEFINED)
MAX)
(RETURN N I L ) ) ) L O O P ( S E T Q L (CDR L)) ) ((NOT ( N U H B E R P (CAR L)>) (RETURN N I L ) ) ( ( G R E A T E R P X (CAR L>) (SETS X (CAR L> (60 L O O P > >
NIL)
(MIN 3) 3 71 (MM 1 71-
2 5
(SETQ c 1 73(MIH 1 7 H A K E F I L E O F FILE U T I L I T I E S
STARTED
P R E T T Y D E F F O R M A T U T I L I T I E S CREATED FILENAME: LISP.DATA.UTILITIES.00 UTILITIES 77(DATE) "29-APR-S1 78-
...
29-APR-81 1 4 : 3 7 : 4 5
14:S8:07"
(EXIT) FSTAT X 0 0 0 0 0 0 3 L I S P . DATA. U T I L I T I E S . 00 » T O T A L P U B L I C PAGES A L L O C A T E D = 0 0 0 0 0 0 0 3
2.1.2
72
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) ( IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN)
DO $ R Z P . L 1 S P X P500 LOADING SIEMENS-INTERLISP
RESET GOOD
-
VERSION
4.0
»•«••«
AFTERNOON.
1(DATE) "29-APR-81
14:39:50"
2 -
(MAX 1 2 U.D.F. WAX
5 4)
..«..» RESET
««*««*
3LOAD( UTILITIES ) PRETTYD6F FORMAT UTILITIES CREATED FILENAME: L I S P . D A T A . U T I L I T I E S . 0 0 UTILITIESCOHS UTIL ITIES 4(MAX 1 2 5 5-
5 4)
UTILITIESCOHS ( (FNS G R O E S S E R P KLEINERP MAX MIN>) 6(DATE) "29-APR-81 7(EXIT)
14:41:14"
Z9-APR-81
14:37:45
73 2.2 Implementierung des Puzzles "Die Türme von Hanoi"
Jetzt
wollen
wir
uns
an die
Aufgabe
wagen , ein
kleines "Programm-System" zu entwerfen: Das Puzzle "Tower-Of-Hanoi" soll modelliert werden. Spielregeln und Hinweise wurden auf dem Merkblatt zu diesem Kapitel bereits mitgeteilt. 2
Beginnen wir mit der Funktion COUNT-TOH , die wir (wie die anderen auch) zuvor auf den File TOWER-OF-HANOI gespeichert haben. Sie berechnet die minimale Anzahl von Zügen für eine gegebene Stapelgröße N : Dem Problem am besten angepaßt ist die rekursive Definition: Wenn nur eine Scheibe zu versetzen ist, so ist das Ergebnis 1. Dieser einfachste Fall ist gleichzeitig Endbedingung und wird in der ersten Klausel des COND formuliert. In der "Einf. Übersicht" hatten wir zum Test auf Gleichheit die allgemeingültige Prädikatfunktion EQUAL kennengelernt. Da hier nur kleine ganze Zahlen verglichen werden, ist die Funktion EQ ausreichend: Sie arbeitet schneller. (Einzelheiten zum Unterschied von EQUAL und EQ werden in Abs. 4.1 besprochen !) Die Rekursion wird in der zweiten Klausel definiert. Wie in der Erklärung des "Tricks" angegeben, benötigt man COUNT-TOH zur Berechnung der Anzahl der Züge für den (N-l)-Stapel zweimal: Einmal um den reduzierten Stapel auf das Zwischenlager zu setzen, zum anderen um ihn nach Versetzen der Scheibe N auch auf das ZielLager zu stapeln. Das Versetzen der Scheibe N wird durch ADD1 berücksichtigt.
3
Wie für kleine Werte N leicht nachzuprüfen, arbeitet COUNT-TOH richtig.
10 Überraschend ist die schnelle Zunahme der benötigten Züge für größere Stapel. Für N=31 ist das Ergebnis
2.2
7k
(IN) (OUT) (OUT) (OUT ) (OUT ) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT ) (It.) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT ) (If.) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT ) (OUT) (OUT) (IN) (Ol'T) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OIIT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (CUT) (IN) (OUT) (OUT)
DO i R Z P . L I S P X P500 L O A D I N G SIEMENS-INTERLISP
GOOD
-
VERSION
4.0
MORNING.
1LOAD(TOMER-OF-HANOI) P R E T T Y D E F FORMAT T O W E R - 0 F - H A NO I CREATED F I L E N A M E : L I S P . D A T A . T O W E R - 0 F - H A N O I .03 TOWER-OF-HANOICONS TOWER-OF-HANOI 2(PP
3 0 - A P R -81
10:55:43
COUNT-TOH)
>
( Q U O T I E N T I f l U O T I E N T U U O T I E N T (OUT) (CUT) (IN)
A ( 1 2 27-
3 4)
8 NIL 28C NIL
19(TOUER (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP (STEP T 30-
-OF-HANOI) 1 MOVE 1 FROM A TO 2 H O V E 2 FROM A TO 3 MOVE 1 FROM B TO 4 M O V E 3 FROM A TO 5 M O V E 1 FROM C TO 6 MOVE 2 FROM C TO 7 MOVE 1 FROM A TO 6 MOVE 4 FROM A TO 9 MOVE 1 FROM B TO 1 0 MOVE 2 FROM B TO 11 M O V E 1 FROM C TO 1 2 MOVE 3 FROM 8 T O 1 3 MOVE 1 FROM A TO 14 M O V E 2 FROM A TO 1 5 MOVE 1 FROM B TO
A NIL 31B NIL 31c ( 1 2 33-
3 4)
(TOWER - O F - H A N O I ) (A E M P T Y ) T
ik(RESET -TOH 7) ( 1 2 3 4 5 6 7) 35-
(DATE) "30-APR-81 46(EXIT)
11:10:05"
B) C) C) B) A) B) B) C) C) A) A) C) B) C) C)
82
2.2 wird die Liste von FROM reduziert. Liefert die Prädikatfunktion OR den Wert NIL, so liegt ein Fehler vor, der in der dritten Klausel als Meldung ausgegeben wird. (Die Funktion OR evaluiert ihre Argumente der Reihe nach bis eines ungleich NIL ergibt: Dieser Wert ist Wert von OR; andernfalls ist das Ergebnis NIL.)
25 Das "Haupt-Programm" TOWER-OF-HANOI ist ebenfalls eine LAMBDA Funktion, die ihre Argumente evaluiert. STEP wird als Dummy-Parameter gebunden und im ersten Statement auf Null gesetzt. Nun wird TRANSFER-TOH aufgerufen, wobei A, C, B (man beachte die Reihenfolge FROM, TO, SPARE !) als globale Variable mittels QUOTE übergeben werden, um die Evaluierung zu verhindern. Der Parameter N, die Anzahl der Scheiben, wird implizit mittels LENGTH aus der aktuellen Länge der an Stift A gebundenen Liste bestimmt. Das T am Schluß wird beim Verlassen von TOWER-OF-HANOI als
Wert
der Funktion
interpretiert und gedruckt. Damit wird verhindert, daß der Wert der zuletzt gerufenen Funktion TRANSFER-TOH als Wert von TOWER-OF-HANOI interpretiert wird und als unerwünschter Ausdruck nach dem Spielablauf zusätzlich erscheint. 2 7 In 22 hatten wir RESET-TOH aufgerufen. Zur Demonstration sehen wir uns nochmals die Listen von A, B und C an: Es ist die Start-Situation des skizzierten Beispiels. Nun lassen wir TOWER-OF-HANOI arbeiten. Der Ausdruck ist selbsterklärend und, wie wir feststellen, richtig. Anschließend sehen wir uns die Ziel-Situation an: Der Stapel wurde ordnungsgemäß versetzt. 33 Rufen wir nochmals TOWER-OF-HANOI, so wird der Fehler erkannt und gemeldet. Mit RESET-TOH kann nun ein neuer Lauf vorbereitet werden, usw. Das Puzzle wurde mit allen Hilfsfunktionen auf den File TOWER-OF-HANOI geladen.
83 2.3
2.3.1
Ü B U N G S A U F G A B E N
Mengen-Operationen Eine Menge ist eine Zusammenfassung von Objekten unserer Anschauung oder unseres Denkens zu einem Ganzen. Eine Liste mit Atomen kann dann als Menge angesehen werden, wenn die Reihenfolge der Atome keine Rolle spielt. Einige Mengen-Operationen mittels Euler-Venn Diagrammen dargestellt : Vereinigung AVB
Durchschnitt AAB
Differenz A\B
Untermenge AcB
Beispiele zu Funktionsdefinitionen : (MEM-SET (EQU-SET (ISA-SET (MAK-SET (UNI-SET (INT-SET (DIF-SET (SUB-SET
"Y '(X Y z) ) M X Y ) "(Y X ) ) '(X Y X Y Z) ) '(X Y X Y Z) ) '(X Y ) '(Y Z) ) M X Y ) M Y Z) 1 M X Y ) M Y Z) ) '(X Y ) '(Z Y X) )
— » •«• » • • *
T T NIL (X Y Z) (X Y Z) (Y) (X) T
= = = =
A*/B AnB A\B AcB
(Hinweis i In Sikl6ssy /Si76/, Abs.5.1 sind einige Beispiele angegeben) 2.1.2 Infix-Präfix / Präfix-Infix
Transformationen
Die in "normaler" Infix-Notation gestellte Aufgabe Z = A * ( B + C ) » D
i
/
\ * / \
sollte nach Infix-Präfix Transformation ergeben (SETQ Z (TIMES A (EXPT (PLUS B C ) D ) ) ) Für die Transformation ist die Darstellung als Baum-Struktur hilfreich;
'f
/
\
+
Die Umkehrung, das Ergebnis der Präfix-Infix Transformation, sollte die Liste ergeben
B
/
D \
C
(Z = A • (B + C ) 4 D ) (Hinweis : W i n s t o n + H o r n /WH81/ t Kap.12 enthält entsprechende
Funktionen)
2.1.1 Symbolische Differentiation eines Polynoms Differentiationsregeln :
du dx
0 ,
wenn
u t f(x)
1 ,
wenn
u = X
du & 'JLDCK-C )
Das Roboter-Programm benutzt ziel-orientierte Prozeduren: PUT-ON, um Blöcke aufeinander zu setzen; PUT-AT, um Blöcke auf einen spezifizierten Platz zu stellen. PUT-ON ruft FINDSPACE und anschließend PUT-AT. PUT-AT ruft GRASP, M0VE-0BJECT und UNGRASP. Um das Ziel zu erreichen, müssen Hindernisse ggf. mittels MAKE-SPACE oder CLEAR-TOP beseitigt werden. Die Funktionen agieren als "Gemeinschaft von Experten". Sie können sich untereinander (ggf. rekursiv) aufrufen. REM0VE-SUPP0RT und ADD-SUPPORT sind Hilfsfunktionen zur Aktualisierung der PropertyListen.
Ol
( (MOVETO (.-M t) ) (feUhsP lu>CK-A ) (tlMETC (1 Sil ) 3UICK-A ) (MoVero ( n i ) ) i &HAS.P BLOCK.- J ") C novero (u 1 * i) iLOCK-ll )
MAKE-&PAC6
- X
• Tuop-ifftCE"
J
GET-WP-OF * •' i MOVt-OßJECT
CLEAR.-TOP MoVe-Hf|top „ K e r w e - s o iVo*r - AW-suppoht
•pur-oM •pur- ftr GRASP CLERR-TOP GET-"Rip-or PUT-AT GÄASf* Hovit-H M w s - oijecT "¡¡.eMovs-soffimT
Die zur Ausführung des o.a. Plan (PUT-ON 'BLOCK-B 'BLOCK-C) sich gegenseitig aktivierenden Funktionen zeigt nebenstehende Skizze ("Wer ruft wen ?"). Zur Beantwortung von Fragen muß vom System eine "Trace"Struktur als Baum aufgebaut werden, Z.B. ist die zur Ausführung des o.a. Planes (PUT-ON 'BLOCK-B 'BLOCK-C) gehörige Struktur nebenstehend skizziert. Sie entspricht der Aufruf-Folge der Funktionen. HAST-DU-Fragen werden durch Suche nach dem Knoten beantwortet, WANN-Fragen werden entweder durch Angabe des toplevel Befehls oder durch Auflistung dieser ("... nachdem ,,, bevor ,..") beantwortet. WIE-Fragen werden durch die Knoten des unmittelbar nachfolgenden Levels, WARUM-Fragen durch den unmittelbar übergeordneten Knoten beantwortet. Existiert kein untergeordneter Knoten, wird "?", existiert kein übergeordneter, so wird "BECAUSE YOU TOLD ME TO DO IT" ausgegeben.
(1977) /Wn77/
MoVe-HH^P Move-HW MoVE-oj\ec.r •Remove - soff o*r W-soPfoex' MCWe-HftUP uioc.ii.frsP
~(ciEMi.-ToP !
Tur-Ofj JLOCK-S 3L0CX •c/
f ^ yMloni? C8 a . . < V
Tur-ar >LO«-J. [ i n ) (GEHSP 3 m m - ?
(HWe-OJiJSCT C u t l ) ( 3 U X K - . 3 )
hJKX-i) (oer-P-i-p-of 3U>CK-A ) I ( TuT-PiT Viiocn-flC -I 5 0 ) (güOSP VOCX-A)
JMX-ft )
89 3.1 Transformation der von Winston angegebenen "Block-Welt" Funktionen auf INTERLISP Ziel und strukturelle Übersicht zur Implementierung einer "Blocks World" sind aus der "Einf. Übersicht" und dem Merkblatt dieses Kapitels zu entnehmen. Die hier im ersten Abschnitt definierten Funktionen wurden (bis auf eine Änderung in MOVE-OBJECT) von Winston /Wn77/ übernommen und auf INTERLISP transformiert. *) Da wir mit den in den nächsten Abschnitten zu programmierenden eigenen Funktionen Gelegenheit haben werden, mehr Erfahrung in LISP zu sammeln, sei dem Anfänger geraten, diese Module mit den zugehörigen Erklärungen zunächst nur im Überblick aufzunehmen und sich erst im Laufe des
Kapitels wieder intensiv
damit zu befassen. Die Funktionsdefinitionen wurden auf den File BLOCKSWORLD gespeichert. Die folgenden Erklärungen sind aus /Wn77/ zitiert : 3
Das Ziel von PUT-ON ist es, ein Objekt auf ein anderes zu stellen. Als erstes wird geprüft, ob beide Objekte identisch sind. In diesem Fall wird REPORT angesprochen und eine erklärende Meldung gedruckt. Normalerweise passiert das nicht; das erste COND hat dann keine Wirkung. Die Aufgabe von PUT-ON besteht darin, einen Platz zu finden und dann (mittels PUT-AT) das Objekt auf diesen zu stellen. Falls FIND-SPACE keinen passenden Platz finden kann, wird MAKE-SPACE
*) Die "Blocks World" von Winston ist ein schönes Übungsbeispiel,um LISP zu lernen. Da sie auch ein vorzügliches "Experimentier-System" ist, sei es dem Leser überlassen,einige Inkonsistenzen in der Behandlung der Fehler-Modi in den Winston-Funktionen zu bereinigen und ein "echtes" Roboter-Programm daraus zu machen.
90
3.1
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) ( IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
DO *
»RZP.LISP P500 LOADING SIEMENS-INTERLISP
«»»»»• GOOD
reset
(OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
VERSION
4.0
•»««»»
AFTERNOON.
1 -
(DATE) " 5-MAT-81
12:22:30"
2 -
LOAD(BLOCKS-WORLD) PRETTYDEF FILENAME:
FORMAT BLOCKS-WORLD CREATED LISP.DATA.BLOCKS-WORLD.il
4-MAT-81
00:41:26
BLOCKS-WORLDCOMS BLOCKS-WORLD 3(PP
PUT-ON)
(MOVE-HAND) 8(PP
UNGRASP)
>
(UNGRASP) 9(PP
GET-R1D-OF)
PLACE )
(QUOTE TABLE) OBJ E C T ) >
3.1
95
(IN)
(PP
CLEAR-TOP)
(OUT) (OUT) (OUT)
> ((1 1 2 ) (1 1 0 ) (6 1 0) 19 4 0) (4 3 0) (3 8 0 ) ) 17-
( S E T S LI (CDR L I ) ) L00P2 (COND ((NULL LV) (TERPRI) (GO L 0 0 P 1 ) ) ) ( T A B (CAR Y ) ) (PRIN1 (CAR L V ) ) ( S E T Q L V (CDR L V ) ) ( S E T H Y (CDR Y > ) (GO L 0 0 P 2 » (SITS) ia(PP
SITUATION)
> (SITUATION) 19-
(X )
3.3
109
-J
C O R G < -J « Û J < H M R O >- W M H Z W V Û. H T Z
U
O ^ _J X O O
I ^ IM >
RESET-BLOCKS-UORLD)
) (COMMON-AREA-P S - L I M I T S 1 S - L I M I T S 2 > > (COMMON-SPACE-P)
(COMMON-SPACE-P 2 45-
'((0
2)(0
2!(0
2)I
'((0
2)(0
21(0
2))
)
(COMMON-SPACE-P 0
«((0
21(0
2M0
21)
M i l
3> (0
2M0
2))
)
(TEST ' ( 1 9 0 ) 'BLOCK-A) ((BLOCK-A 1 9 0 ) ) 23(TEST ' ( 9 1 0 ) ' P Y R A M I D ) ( ( P Y R A M I D 9 1 0) ( B L O C K - A 24( S E T 0 R E S E R V E (ASSOC (BLOCK-A 1 9 0) 25-
1 9
'BLOCK-A
0)) RESERVATIONS))
(CAR R E S E R V E ) BLOCK-A 26(CDR R E S E R V E ) (1 9 0) 27(SETQ R E S E R V A T I O N S (REMOVE R E S E R V E (RESERVATIONS RESET) ((PYRAMID 9 1 0 ) I 28-
RESERVATIONS))
1U2
k.2 Wir etablieren darum die Assoziations-Liste RESERVATIONS, in die vergebene Plätze zusammen mit dem Namen des Objektes (als Schlüssel des Punkt-Paares) eingetragen werden
sollen.
21 Zur Vorübung definieren wir eine Funktion TEST, die Eintragungen in RESERVATIONS vornimmt. Die Parameter sind NEWPLACE und OBJECT. Das innere CONS bildet das Punkt-Paar aus beiden Argumenten; das äußere CONS fügt es an den Anfang der RESERVATIONS-Liste
ein.
22 Rufen wir TEST mit einem freien Platz für BLOCK-A auf, wird
der
neue
Status
Nach nochmaligem Aufruf
von
RESERVATIONS
ausgegeben .
( mit einem anderen freien
Platz für PYRAMID ) wird die neue Eintragung
ergänzt.
(Man wundere sich nicht, daß "kein Punkt zu sehen" ist: Von INTERLISP wird diese äquivalente Form ausgegeben ! ) 2b Da der Schlüssel atomar ist, können wir mit ASSOC auf RESERVATIONS zugreifen und z.B. das Punkt-Paar mit dem Schlüssel BLOCK-A auf RESERVE speichern. Der CAR- und CDR-Zugriff auf RESERVE überzeugt uns, daß hier tatsächlich ein Punkt-Paar von OBJECT und NEWPLACE vorliegt. 27 Das Löschen von Eintragungen auf RESERVATIONS kann mittels REMOVE und Umspeicherung, wie im Beispiel demonstriert,
erfolgen.
Nun zu CLEARP, einer schon komplexen Funktionsdefinition: Die Eingangsparameter sind NEWPLACE und OBJECT. Mit den ersten Statements im PROG-Rumpf speichern wir von OBJECT am NEWPLACE die OBJECTLIMITS und auf BW die Namen der "Block-Welt"-Bausteine
einschließlich Box.
Die Iterations-Schleife beginnt mit der Endbedingung: Ist die Liste BW abgearbeitet, so war bisher
"alles
klar" und die "Buchung" auf RESERVATIONS kann wie eben geübt erfolgen. Der aufrufenden Funktion wird ein T
k.2
1kj
zurückgegeben. War die BW-Liste noch nicht abgearbeitet, so "fällt COND durch". Mit dem nächsten SETQ wird das erste Element von BW an TESTOBJECT gebunden und anschließend der zugehörige OLDPLACE ermittelt. Nun muß RESERVATIONS daraufhin durchgesehen werden, ob das TESTOBJECT noch von einer früheren "Buchung" eingetragen ist, inzwischen aber auf den neuen Platz gestellt wurde. Wie zuvor am speziellen Beispiel geübt, greifen wir mit ASSOC auf das gesuchte Punkt-Paar zu und speichern auf RESERVEDPLACE die "gebuchten" PlatzKoordinaten. Das nachfolgende COND prüft, ob OLDPLACE gleich RESERVEDPLACE ist und löscht gegebenenfalls. Das sich anschließende COND prüft, ob das aktuelle TESTOBJECT der Liste BW gleich dem Argument OBJECT ist. Wenn ja, so ist der anschließende Programmabschnitt nicht relevant und wird übersprungen, die BW-Liste reduziert und die Iterations-Schleife bei LOOP fortgesetzt . Andernfalls muß im restlichen Programm zweierlei geprüft werden: Erstens, ob das OBJECT am NEWPLACE mit schon "gebuchten" Plätzen kollidiert und zweitens, daß nicht als "frei" ein Platz "verbucht" wird, der zwar frei wird, tatsächlich aber z.Z. noch belegt ist. denn der einarmige Roboter kann Jeweils nur einen Baustein versetzen ! Die erste Bedingung wird im COND geprüft, dessen einzige Klausel hier mit einem atomaren Prädikat beginnt: War RESERVE ungleich NIL, so existiert ein "gebuchter" Platz für TESTOBJECT, dessen TESTLIMITS nun zu ermitteln sind. Im eingebetteten COND wird geprüft, ob die TESTLIMITS des neuen Platzes sich mit den OBJECTLIMITS überschneiden. Wenn ja, so wird NIL der aufrufenden Funktion zurückgegeben.
IM
h.z
1^5
(L'I) NUN OUT) OUT) ( IM) ( OUT ) (MIT) (DUT) (OUT) (IN) (•UT) (Ü'JT) (OUT) (IN) (OUT) (GUT) OUT) ( I") (•UT) (OUT) (OUT) (IN) (NUT) (DUT) ('JUT) (IN) (DUT) (UUT) OUT) (IN) (DUT) (DUT 1 ( UUT ) ( IN) (OUT) (OUT) (UUT) (IN) ( DUT ) (DUT) (DUT) (IN) (•UT) (DUT) (DUT) (IN) (DUT) (UUT) (•'.ITI ( IN) OUT) OUT) (JIJT) ( IN) (OUT) CJUT) (OUT)
(RESET-BLOCKS-WORLD) T 30(SETQ R E S E R V A T I O N S N I L ) (RESERVATIONS RESET) NIL 31(CLEARp NIL 32-
1(6
10)
' BLOCK-A)
(CLEARp NIL 33-
K5
10)
I BLOCK-A)
(CLEARp T 34-
1(4
1 0)
'BLOCK-A)
RESERVATIONS ((BLOCK-A 4 1 0 ) ) 35" (CLEARp T 36-
1(9
4 0)
RESERVATIONS ((BLOCK-D 9 4 37"
0)
'BLOCK-D)
(BLOCK-A
(CLEARP NIL 38-
'(8
3 0)
'PYRAMID)
(CLEARP T 39-
K8
3 0)
1
RESERVATIONS ( ( B L O C K - D 8 3 0) 40-
BLQCK-D)
(BLOCK-A
(CLEARp NIL 41-
K3
10)
'PYRAMID)
(CLEARp T 42-
i(9
1 0)
'PYRAMID)
RESERVATIONS ((PYRAMID 9 1 0) 43-
4 1 0))
(BLOCK-D
4 1 0) )
8 3 0)
(BLOCK-A
4
10))
1^6
h.2 Für die zweite Bedingung werden die TESTLIMITS des TESTOBJECT vom OLDPLACE berechnet und geprüft, ob sie sich mit den OBJECTLIMITS überschneiden. In diesem Fall ist das Ergebnis NIL; sonst wird die Liste BW reduziert und die Iterations-Schleife bei LOOP fortgesetzt. Zum Test von CLEARP stellen wir "Situation 0" mittels RESET-BLOCKS-WORLD ein. Die RESERVATIONS-Liste muß noch explizit gelöscht werden; später werden wir dieses Statement in die Funktion DROP aufnehmen, die von RESET-BLOCKS-WORLD gerufen wird.
31 CLEARP, aufgerufen für BLOCK-A mit den Koordinaten des Platzes von Block-C, ergibt NIL. Auch der folgende Test kollidiert mit Block-C. Erst der dritte Versuch ist erfolgreich. Wie wir sehen, ist in RESERVATIONS der neue Platz "gebucht" worden. 35 Was passiert, wenn wir die eigenen Koordinaten eines Bausteins (z.B. BLOCK-D) eingeben? Das Ergebnis ist T, denn der letzte Programmabschnitt in CLEARP wird in diesem Fall übersprungen und in RESERVATIONS die Eintragung vorgenommen. 37 Beim nächsten Aufruf prüfen wir für die PYRAMID einen teilweise von Block-D belegten Platz: Erwartungsgemäß ist das Ergebnis NIL. 38 Was ergibt sich aber, wenn wir diesen Platz für BLOCK-D selbst prüfen? Das Ergebnis ist T !
Diese erwünschte
Eigenschaft, einen Baustein verrücken zu können, resultiert aus dem Überspringen des letzten Programmabschnitts in CLEARP, wenn es sich um das Objekt selbst handelt. RESERVATIONS enthält den letzten Eintrag des neuen Platzes für BLOCK-D. Wir sehen, daß der alte Eintrag vom vorangegangenen Aufruf (mit den eigenen Koordinaten) wieder gelöscht ist, wie es im zweiten COND von CLEARP programmiert wurde.
h.2
fhj
UO Fragen wir Jetzt, ob für die PYRAMID auf (3 1 o) freier Platz vorhanden ist (in "Situation 0" ist er frei !), dann wird wegen der "Buchung" von BLOCK-A für (h 1 o) diese Frage verneint. Erst ein wirklich freier Platz wird vergeben und in RESERVATIONS "gebucht". Die Funktion FIND-SPACE wird zweckmäßig unterteilt in die Subfunktionen FINDSPACETOY für die Bausteine und FINDSPACE1 für Box und Tisch. FINDSPACETOY ist schnell programmiert. Die Parameter sind SUPPORT und OBJECT. Mit dem ersten COND wird geprüft, ob SUPPORT die Eigenschaft SUPPORTP gleich T hat. Wenn nicht, so ist das Ergebnis NIL. Andernfalls wird der PLACE von OBJECT berechnet; er ist vereinbarungsgemäß gleich dem TOPCENTER von SUPPORT. CLEARP prüft, ob Raum verfügbar ist. Wenn ja, werden der aufrufenden Funktion die PLACE-Koordinaten übergeben, andernfalls ist das Ergebnis NIL. kk Nach RESET-BLOCKS-WORLD und Löschen von RESERVATIONS testen wir FINDSPACETOY. b6 Bei SPHERE und PYRAMID als unterstützendem Objekt für BLOCK-A ist das Ergebnis von FINDSPACETOY gleich NIL{ "Buchungen" erfolgen nicht. Warum wird dieser Sonderfall in FINDSPACETOY abgefangen und nicht der Kompetenz von GET-POSSIBLE-SUPPORT überlassen? Nicht nur aus Effektivität s gründen, sondern zur Vermeidung von Folgefehlern: CLEARP würde irreversible Eintragungen falscher Werte in RESERVATIONS vornehmen! \
k8 Im dritten Beispiel ist auf BLOCK-C für BLOCK-A Platz vorhanden. Im nächsten Beispiel wird eine schon bestehende Situation, BLOCK-A auf BLOCK-B, eingegeben: Entsprechend der Programmierung ist das Ergebnis von CLEARP gleich T; also wird in diesem Fall der PLACE ausgegeben. Dagegen ist für BLOCK-D auf BLOCK-B kein Platz vorhanden.
148
4.2
51 RESERVATIONS zeigt, daß die erste "Buchung"
erhalten
ist, die zweite Eintragung wurde beim letzten Aufruf wieder gelöscht. 52 Für die weiteren Tests setzen wir die "Block-Welt"
zu-
rück auf "Situation 0" und löschen RESERVATIONS. Bei Bausteinen gibt es vereinbarungsgemäß nur einen Platz, auf den ein anderer Baustein gestellt
werden
kann. Diesen Platz zu finden war Aufgabe von FINDSPACETOY. Dagegen gibt es bei Box und Tisch mehrere Möglichkeiten: Die zuständige Funktion FINDSPACE 1 wählt diese Plätze durch Aufruf des Zufallsgenerators RAND aus. Die Eingangsparameter von FINDSPACE1 SUPPORT (entweder BOX oder TABLE) Tests
ergaben ,
daß
etwa
sind wieder
und
OBJECT .
50 Versuche
Da
ausreichen ,
um einen Platz zu finden, falls einer vorhanden ist, wird der Iterations-Zähler I auf 50 gesetzt. Zunächst werden die SUPPORTLIMITS berechnet und daraus mittels C....R -Funktionen die x - , y-Grenzwerte ermittelt. Die Iterations-Schleife beginnt bei LOOP und prüft zuerst das Abbruchkriterium: Falls der
Iterations-Zähler
I gleich Null ist, wird NIL zurückgegeben. Andernfalls werden die PLACE-Koordinaten mit Hilfe von RAND ermittelt: Der erste RAND-Aufruf ergibt die
"zufällige"
x-, der zweite die y-Koordinate. Dabei werden mittels ADD1 bzw. SUB1 die Wertebereiche so vermindert, daß kein Randpunkt ausgegeben wird. Die z-Koordinate ist der Property-Liste zu entnehmen: Beim TABLE ist sie gleich Null, bei der BOX entsprechend der Höhe des "materiellen Bodens". Mittels LIST werden die Koordinaten zusammengefaßt und durch SETQ an PLACE gebunden. Nun muß noch geprüft werden, ob der "zufällig"
ausge-
wählte PLACE auch frei ist, was CLEARP innerhalb der COND-Klausel besorgt. Wenn ja, wird PLACE zurückgegeben ; andernfalls wird I vermindert und ein weiterer Versuch
gestartet.
1 ^ 9
( IN)
(PP
(•UT) (OUT) (•UT)
(AUT) (DUT) (DUT) (•UT)
(DllT) (IM) (•UT) (DUT)
(•llT) (IM)
(J
9
4))
BLOCK-C)
( G R A S P B L O C K - A ) (MOVETO (MOVETO ) BLOCK-B) (6
1 2 ) )
BLOCK-C)
(MOVETO ( 9 4 2 ) ) ( G R A S P B L O C K - D ) (MOVETO ( 1 9 B ) ) (UNGRASP B L O C K - D ) (MOyETO {¡,3 2)) (GRASP SPHERE) (MOuETO ( 1 9 1 0 ) ) ( U N G R A S P S P H E R E ) (MOVETO ( 8 8 0 . 1 0 0 0 0 0 ) ) ( G R A S P BOX) (MDVETO ( 5 5 0 . 1 0 0 0 0 0 ) ) (UNGRASP BOX) (MOVETO O B 2 ) ) ( G R A S P P Y R A M I D ) (MOVETO ( 5 5 2 . 0 9 9 9 9 9 ) ) ( U N G R A S P P Y R A M I D ) ( G R A S P P Y R A M I D ) (MDVETO ( 3 8 2 ) ) (UNGRASP P Y R A M I D ) (MOVETD ( i 9 l O ) > ( G R A S P S P H E R E ) ( M O V E T O ( 2 6 2 1 ) ( u N G R A S P S p H e R E ) (MOVEyO (GRASp B L D C K - D ) ( M O V E T O (9 7 2 ) ) (uNGRASp
(1 9 8 ) ) BLOCK-D)
(MOVETO ( 1 9 6 ) ) ( G R A S P B L D C K - C ) (MOVETO (B 5 2 1 ) ( U N G R A S P B L O C K - C ) (MOVETO ( 1 9 4 ) ) ( G R A S P B L O C K - B ) (MDVETO ( 5 9 2 ) ) (UNGRASP B L O C K - B ) (MOVETD Jedes Resultat kann selbstverständlich in ähnlicher Weise seine Aktionen als Substruktur in die "Trace"-Liste einbinden : Es liegt somit ein rekursives Repräsentationsschema vor, das in komplizierten Fällen tief geschachtelt ist. Die Generierung weiterer Substrukturen wird gestoppt, wenn Funktionen angesprochen werden (z.B. MOVE-HAND), die im Sinne des Frage/Antwort—Systems uninteressant sind. Z.B. soll UNGRASP nur zurückliefern : (
(UNGRASP object) )
Die dazu notwendige Programmierung des RETURN ist : (RETURN (LIST (LIST 'UNGRASP OBJECT) > Einige interessante Probleme ergeben sich z.B. beim Aufruf von GET-RID-OF innerhalb der Schleife in MAKE-SPACE , sowie bei GRASP , wo CLEAR-TOP gerufen oder auch nicht gerufen wird. MAKE-SPACE gibt nicht nur T f sondern den Platz zurück. Hier muß der Platz mit dem "Trace" in eine Liste "gepackt" werden und die aufrufende Funktion PUT-ON muß diese wieder "entpacken" ! Ausgehend von der "Situation O" f (PUT-ON 'BLOCK-B
sollte der Befehl
'BLOCK-C)
z.B. folgende "Trace"-Struktur ergeben (Level handschriftlich n a c h g e t r a g e n ! ) : ( ( PUT-ON BLOCK-B BLOCK-C ). 1 0 1 ( ( PUT-AT BLOCK-B (6 1 2) ), •T { 3 3 2 ( ( GRASP BLOCK-B ) 2 3 3 ( ( CLEAR-TOP BLOCK-B ), 3 k H 3 UL « J Z O
m
UJ
UJ
< K I L
Z V LLI 0 o — z oO V ti — —
m o i
UJ X
-jo
O H -
LL.
U J -J a> o > UL > A «-»OA
O V> O UJ W UL UL M
to »o lu
- 4 UJ O.
tO
o ^
~>
a
JU J O —
O Ul -» «n a UI U—
O
oc
Ck.
K
RJ
o
a. a.
—
n
1
•
A A o
*A.
—•
O W < — O _l ha. o z uuj ar Ul o o o 3 —3 O m a. o
O
et
a.
tv>
o r> o
*
_>
z
o
~
o.
UJ
—i O
O
«oflfO O *o V
o. to < o¿ O
o o
3
UJ 1
O -> 1 M CD DO. h- to a. < uj o oc r W o OC < Ui
CD
t-
£L UJ
TO
co o
~>
- û.
w
O X
«
a.
h-
3 A.
a h
UJ TO
z> r: 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 M c n o D o n c n n a o o a • r; • n o o o r a r i o o r a o a o n n • rz rz
5.1
167 Auch die Funktion GRASP hat zwei logische T-Ausgänge. Beim ersten ist das bekannte Schema anzuwenden, doch beim zweiten ist zusätzliche Überlegung notwendig: Die an Gl, G2 oder G3 gebundenen "Tracer" werden zwar wie gehabt verknüpft, jedoch kann es sein, daß einige (oder alle) NIL sind, falls sie nicht innerhalb der COND-Klauseln angesprochen wurden! Dieser Fall muß mit Hilfe von REMOVE bereinigt
werden.
Die Funktion CLEAR-TOP ist komplizierter: Die erste Sonderbehandlung ist wegen GET-RID-OF
erforderlich,
denn diese Funktion kann innerhalb der Schleife mehrmals hintereinander aufgerufen werden. Das
"zeitliche
Nacheinander" legt es nahe, die Liste G1 mittels APPEND zu erweitern. (Vgl. letztes Beispiel der Vorübungen : Das LIST erzeugt das von APPEND benötigte Klammer-Paar
zusätzliche
!)
Die zweite Sonderbehandlung ergibt sich beim RETURN: Damit kein fehlerhafter "Level-Sprung" im
"Trace"-Baum
erzeugt wird, muß die Liste mittels CONS in Gl fügt werden, (vgl. Vorübung
einge-
!)
19 In der Funktion MAKE-SPACE liegt GET-RID-OF wie bei CLEAR-TOP innerhalb einer Schleife. Dieser Fall muß darum die gleiche Sonderbehandlung erfahren. Eine zusätzliche Komplikation ergibt sich beim RETURN: Hier ist nicht
(wie bei anderen Funktionen) nur T zu über-
geben, sondern der weiter zu verarbeitende Wert SPACE ! Wir "packen" darum eine Liste, die als CAR den Wert von SPACE enthält und als CDR den gewünschten
"Tracer".
In der Funktion PUT-ON muß die von MAKE-SPACE
"gepackte"
Liste wieder "entpackt" werden: Mittels CDR wird auf den "Trace", mittels CAR auf den PLACE zugegriffen. Für die Fehlermeldung ist die PLACE-Information maßgebend und wird darum im zusätzlichen COND behandelt. Wie bei GRASP
168
5.1
X 3
«t X
~
fr«_>
o LU fr-
*
>o —> CD o O D. w oc CL fr1- uì o _J
m co to io fr-
a . _J
a. O
Ko to o < »- 3 UJ z i X o£ 3a. o iO C O < M a.» eC D — w h-c-4 - CJ
p
-
-
3 3 2 ~' 3 n n n «- n C ?•
t—
>—
3 r 3 3 3 B o «- c 3 a o
170
5.1 ist beim RETURN ein REMOVE nötig, denn G1 könnte NIL sein, falls FIND-SPACE bereits fündig geworden ist.
21 Nun sind alle notwendigen Änderungen erfolgt. Wir testen das neue System, nachdem wir es in "Situation 0" zurückgesetzt haben: 22 Der Befehl (PUT-ON 'BLOCK-B 'BLOCK-C) ergibt genau den "Trace", dessen strukturierte Darstellung im Merkblatt als Beispiel skizziert wurde. 23 BW-PLAN liefert den zugehörigen Plan. Geben wir anschließend (PUT-ON 'PYRAMID 'BLOCK-C) als Befehl, so wird MAKE-SPACE gerufen, dessen "Sonderbehandlungen" hiermit getestet werden. 25 BW-PLAN zeigt, daß PLAN fortgeschrieben wurde. Die Skizzen machen den Handlungsablauf nochmals anschaulich. 27 Mittels SITUATION lassen wir uns den neuen Status ausgeben, der Ausgangs-Situation für die weiteren TestBeispiele ist. Mit DROP "vergessen" wir die Vorgeschichte . Mit den folgenden vier Befehlen setzen wir die Blöcke in die Box. (Der "Trace" des dritten Befehls hat die gleiche Struktur wie unser erstes Test-Beispiel.) 32 BW-PLAN zeigt den Plan nach dem letzten DROP-Befehl. 33 Die aktuelle SITUATION ist wieder Ausgangs-Status für den folgenden Test. Mit DROP wird die Vergangenheit "vergessen". Für die neue Situation wird mit (CLEAR-TOP 'BOX) die "Sonderbehandlung", das GET-RID-OF innerhalb der Schleife, getestet. 36 BW-PLAN listet den Plan nach dem letzten DROP-Befehl. SITUATION zeigt den aktuellen Status. Aus den Skizzen ist der Handlungsablauf nochmals zu ersehen.
5.1
171
— o X — •< — c¿ o >o. ro. H «/) «-' < 0t m o
« —
^ O O
w
®
rg
h- ^ < 1 h- w z> a. o — ® 1 ^ o O -J «
I oí > a. l< 1 b-
u. a w i — o
ec t —. >- ~ O
A
^
^ O — o o _» 00 X < a. te v> > < a a: O O 2 » 3 U — o ~ o
=0 O. hVO Ul < > eC o
a X
— ® a N 1 ^ X m o < o tC H J > — a a. o ft- o* CO to 111 «X < > oc OÍ a o es r z — r>
o o ~ •O i— HX X »
^ — — o
O O _J a
o LU -> a a a. i «n UJ < > t = * a 3 d o X i w «rt *•» *•» w W cnI
N • M a n H B
1 — * «M O a r_i (D •-
- >o.a. — z z a O »
II M
£ •< Oí >a.
0 a_ O. to LO O < oc fcK O Ul l3 2 > — 3 o X
r* X l—i 4 — 'O oc — w y z a a. «f H o jUlt-Q. Q. > UJ Vi » o > < > X o te i BJ - I O -O w w w W N
cC M UJ « X a to o 1 * 1 o a _» A 1 1 » 1 1 1 1 1 1 1 1 1 1 t i i 1 1 1 1 1 1 1 i i i i i i i t i i i i z i o i 1 )- t < 1 r? 1 1- 1 CO 1 —» 1
II H • «
U o — o 1 CM fM M X X O »4 (SI < O -i oc o - j N - J •-« «O (M >-UJ CO z — — O- OC z N H lu m z> u II co n O «M UJ Ul oc z n a: • o -» i«l N U i U l CD-I X UJ - J < M ^ r g a tf •-> o •— Z — — to o z N o II II o o o o UJ ^ o rsi o CD a o n < •— a- f\j _ i LU il z ® oc » - H o O H * a a U a o a u a fi a W £û a a a H Ul o a NI 1 n a vi o a a a a _) a il a (D a a < il 1 » a * a — O a a O D II
1» » CD tri O I II ^ U «M O II o o • -J H m CD H o
X O M l u «x J t f H N U m > a < a « ini —* t- w w M a
H • CD 0 M 1 > 1 * H < O • X a • 1 m _J CD r-t • « • < n 1 H * • Lli u » a • _J _» • < A H •> H • • II H o —« • z i n II >-«
a it ^ o a o n _ j lu o f i i h il CD H IA 03 n a «0 a m cd H a 1 II a O (M X. a UJ UJ Z a LU O il o -J IO N O UJ a o o il < _1 a < - i m _j a UJ < _ .-4 «SI _ I oc n a _J CD Z «— — « O 1— a a. z a O. — u H il a M iA a to to II 1- n I»II oc n et oc o O o II o. H a. a. o. n II a. > D. a u a CD Z> LO a i/i il t lO a H O 1 1 > n UJ > a. a > hf- H N et fcec hK O U Ui eC O H o a uj o UJ R UJ a LU U UJ UJ • CL il CL OC < NI û. - J CL X ce B CD o O — — >- O 3 a < o GÛ o a h- o l/l Û CL Ü It
o
O (M tu —f r- m œ < M ^ fsl h Z - w «
n UJ U 3 » Kl —r tt k H «o • H
1 i t 1 i 1 1 i t 1 1 i i i 1 1 i i i i 1 1 i i i i i t 1 1 1 i 1 i 1 1 i i i 1 i i i i t i i i i 1 1
a
« a a u ^ a u _ j a —• 43 a Z — u a H a H
1 1
i 1 1 1 1 1 1 1 1 ( O z 1 z O 1
a » n a
o. \ V) 1 < V> 1 oc a i o a. i 1 O O 1 Z Z I 1 < < » rI I 1 h N
— a. o OC - 1 1 o ) (MOVETO (6 1 Z)) (MOVETO (9 4 2)) 33-
n (7 (6 (9 (9
(GRASP B L O C K - A ) (GRASP B L O C K - B ) (GRASP P Y R A M I D ) (GRASP B L O C K - C ) (GRASP B L O C K - D )
(MOVETO (MOVETO (MOVETO (MOVETO (MOVETO
7 9 5 9 7
BLOCK-O
((GRASP P Y R A M I D ) ) ( ( M O V E - O B J E C T (9 9
O.JOOOOO)))
2 . 0 9 9 9 9 9 1 1 IUNGRASP B L C C K - A ) 2.099999)) (UNGRASP BLOCK-8) 2)) ( U N G R A S P P Y R A M I D ) 2 . 0 9 9 9 9 9 ) ) (UNGRASP B L O C K - C ) 2 , 0 9 9 9 9 9 ) ) (UNGRASP B L O C K - D ) )
(S I T U A T ION) SITUATION BLOCK-A BLOCK-B BLOCK-C BLOCK-D SPHERE PYRAMID (•••IllSltllllllll • f l l l l I K I I I l I l K l l I t u K l I i l E l ï l ï I . l t i û i ï j s t l i s i E t S s i i B i i l VALUE L B - M A Y - B L 03 I 07121 INDICATOR BOX BOX BOX BOX TABLE TABLE S NIL NIL NIL NIL NIL NIL DU IP RP EO CR TT LE Y D- -S BU YP P O R T S PLACE (7 7 0 . 1 0 0 0 0 0 ) (7 9 0 . 1 0 0 0 0 0 ) (9 9 0 . 1 0 0 0 0 0 ) (9 7 0 . 1 0 0 0 0 0 ) (6 5 0) U 3 0) SIZE (2 2 2)
HAND GRASPING NIL HAND P O S I T I O N (9 7 2 . 0 9 9 9 9 9 ) T 34(DROP) NIL 35-
173
5.1
( C L E A R - T O P 'BOX) ( ( C L E A R - T O P B O X ) K G E T - R I D - O F B L O C K - D I ( I P U T - A T B L O C K - D (Ò 3 O > ) ( ( G R A S P B L o C K - D I ) ( ( M O V E - O B J E C T (6 3 0 ) ) ) ( ( U N G R A S P B L O C K - D ) ) ) ) K G E T - R I D - O F B L D C K - C ) ( ( P U T - A T B L O C K - C (3 5 0 ) ) ( ( G R A S P B L D C K - O ) ((MOVE-OBJECT O 5 O D ) K U N G R A S P BLDCK-C)))) ((GET-RIO-OF BLOCK-B) ( ( P U T - A T B L O C K - B (8 4 0 ) ) ( ( G R A S P B L O C K - B ) ) ( ( M O V E - O B J E C T (8 4 0 ) ) ) U U N G R A S P B L O C K . B ) ) ) ) ( ( G E T - R I D . O F B L O C K - A ) ( ( P U T - A T B L O C K - A (1 3 0 ) ) ( ( G R A S P B L O C K - A ) ) ( ( M O V E - O B J E C T (1 3 0 ) ) ) ( ( U N G R A S P B L O C K - A ) ) ) ) ) A6M G R A S P N B L 0 C K - D ) ( M O V E T D (6 3 Z D ( U N G R A S P B L O C K - D ) ( M O V E T O (9 9 2 . 0 9 9 9 9 9 ) ) ( G R A S P B L O C K - C ) ( M O V E T O (3 5 2 ) ) ( U N G R A S P B L O C K - C ) ( M O V E T O (7 9 2 . 0 9 9 9 9 9 ) ) ( G R A S P B L O C K - B ) ( M O V E T O (8 4 2 ) ) ( U N G R A S P B L O C K - B ) ( M O V E T O (7 7 2 . 0 9 9 9 9 9 ) ) ( G R A S P B L O C K - A ) ( M O V E T O (1 3 2)) ( U N G R A S P B L O C K - A ) ) 37-
B(IS-I)C M
BO*|880)
MIRA)
AN D M TFCSO)
MISO) X-V (M)
D M
(KM)
TILL) /^~C(UO)
X
SON(EAO)
=>
X fa
CTLSO) AM
ITS»)
1 W BLIW)
TABLE TALLE
(SITUATION) SITUATION
BLOCK-A
BLOCK-B
BLOCK-C
INDICATOR
VALUE
18-MAY-61
03 : 1 0 1 1 B
SUPPORTED-BY DIRECTLY-SUPPORTS PLACE SIZE TYPE COLOR SUPPORTP
TABLE NIL (1 3 0 )
BLOCK GREEN T
TABLE NIL (8 4 0 )
BLOCK RED T
TABLE NIL (3 5 0 ) (2 2 2» BLOCK BLUE T
• H33BlE3tBl|333E33333E3llSE B 3 3 E I I B 3 I E 3 I E ( 3 3 3 3 3 E S
BLOCK-D :33333:E33 TABLE NIL (6 3 0 ) < 2 2 2) BLOCK RED T
SPHERE
TABLE NIL (4 3 0 ) lilliiiiiliilalii|Ili:ixiciiE(iinti::E::Ei:a:i:::t::is:i:iii:iEc:ti
BOX P L A C E 18 8 0 ) S I Z E (4 4 0 , 1 0 0 0 0 0 ) C O L O R B L U E DIRECTLY-SUPPORTS N I L ILTIII:SI3LILI:IIII(IAIITI9IIII«TITSIIIITI|JFAJ:T(;;I:S::::;IIS:A3SI:::SI:I3TI TABLE P L A C E (5 5 O) S I Z E d o 10 o ) COLOR BLACK DIRECTLY-SUPPORTS (BLOCK-A 8L0CK-B BLOCK-C BLOCK-D PYRAMID SPHERE BOX) liStiii:tiiiiiiiiiiii3itiii|IAIAIIE3I|IIIIIIB3I:::i:A3S:::::IEE:itE:I:i::is::t HAND G R A S P I N G NIL HAND POSITION (1 3 2) T 38(DATE) T^S-MAY-BI J9(EXIT)
03111:53"
17^ 5.2 Bindung des "Trace" an eine Liste als Voraussetzung zur Frage/Antwort-Fähigkeit des Systems
Die im vorigen Abschnitt (5.1) erzeugten "Trace"-Listen wurden nicht gebunden, gingen also verloren. Als Voraussetzung zur Frage/Antwort-Fähigkeit des "Block-Welt" Systems muß auf die vorhandene "Trace"-Struktur zurückgegriffen werden können! Wir werden darum Funktionen definieren, die die "Trace"-Bindung an die Liste TRACER ermöglichen. 3
Da für RESET-BLOCKS-WORLD auch der "Trace" zurückgesetzt werden muß, werden wir zweckmäßig in DROP auch die Liste TRACER löschen.
k
Die Funktion BW-TRACER soll die "Trace11-Bindung an TRACER vornehmen. Im aktuellen Definitions-Zustand der "Block-Welt" ist der "Trace" der Wert des ausgeführten Befehls. Zeitlich nacheinander gegebenen Befehlen sollen auch entsprechend nacheinander angeordnete "Traces" entsprechen. Es bietet sich APPEND zur Verknüpfung an, wobei wiederum LIST zum richtigen Arbeiten notwendig ist! Mittels SETQ wird der "Trace" an TRACER gebunden und somit "abgefangen": Die Antwort ist schlicht "O.K.", wenn kein Fehler entdeckt wurde.
5
Im folgenden wird das Verhalten von BW-TRACER demonstriert: Der Befehl (PUT-ON 'BLOCK-B «BLOCK-C) ist Argument von BW-TRACER; das Ergebnis ist "O.K." .
7
Rufen wir jetzt TRACER auf, so wird der gebundene "Trace" ausgegeben. Das (gegenüber dem Merkblatt-Beispiel) zusätzliche äußere Klammer-Paar dient der Verknüpfung mehrerer Befehls-"Traces" ! Mittels BW-TRACER können wir den "Trace" binden. Wir wollen doch aber nicht jeden Befehl eingebettet in BW-TRACER eingeben! Eine Möglichkeit wäre die erneute
5.2
175
(If.) DO $RZP.LISP r. PSOO LOADING (Al'T ) (PI. T) SIEMENS-INTERLISP - VERSION 4.0 ((¡IT) (UIT> (CM) . . . . . . reset *»»»«* Cil. I? ( ~i I ) (PI T ) GOOD MORNING. mm (CM) 1(Oil) (IN) (DATE) (r i t) "2 2-MAY-8 1 00:34:12" l"l:T) 2(I'M ) LOAD(BLOCKS-WORLD) ( IM (liH ) ( (11: T ) PRETTYDEF FORMAT BLOCKS-WORLD CREATED 22-MAY-81 00:10:46 FILENAME: LI SP.DATA.BLOCKS-WORLD . 55 BLOCKS-WORLDCOMS ((11) (no (FIRSTCOL RESET) BLOCKS-WORLD (urn) mi) 3c.) GETO(DROP) (OCT ) (LAMBDA NIL (• EDITED: "21-MAY-81 23:46:39") (SETH PLAN NIL) (SETH RESERVATIONS NIL) (SETQ TRACER NIL)) ' o 11 r) 4( CL T ) (PP BW-TRACER) ( I'.) (oia) (OI'T ) > (nil (BW-TRACER-ON) c.l'l ) 10( ni T ) ( It ) (PP BW-TRACER-OFF) (oi l ) (oi l )
(INSIDE) 9«INSIDE 'B ' (A B C) ) s 10(INSIDE (B tC>» 11-
'B '(A>) )
(TRACE INSIDE) (INSIDE) 12(INSIDE 'B ' ( ( A B)C) ) INSIDE : SEX « B LIS = ((AB)
C)
INSIDE: SEX = B L I S = IA B) INSIOE: SEX = B LIS = A INSIOE = NIL INSIDE: SEX = B L I S = (B) INSIDE = B INSIOE = 8 INSIDE = (A B) (A B) 13-
(UNBREAK I N S I D E ) (INSIDE) H-
6.1
187
( ii.) (CUT) (CUT) (niII ) (I>.) ( Ol'l ) C 01; T ) (cin > (ir.) (CUT) (OliT) (OI'T) Ci) (OI;T) (LI.'T) (cut ) ( li. >
(nuli ((UT) ( out ) ut ) (0L T) (OI'T) (Cl'T) (I ) (C'T ) (CI I ) ((.MIT ) ( IN ) < r i. i ) ((MIT ) < C IT ) ( II ) (Cl'T ) ( ni 1T ) (0L T ) (If.) ( OI'T ) (OI'T 1 (OI'T ) CI'.) (HI T ) (CL'T ) ( Oli T )
(INSIDE * B * ICA B)C) ) (A B) 15(INSIDE 1(B) '((A B)C) ) NIL 16 -
(INSIDE 'B • ( CB)> ) (B) 17-
(INSIDE "(B) '(CB)) ) (B) 18-
(INSIDE '(8) 1CB) ) NIL 17(INSIDE 'B 'CB> ) B 20(INSIDE 'B 'B ) NIL 21 -
(INSIDE 'B NIL) NIL 22-
(INSIOE 1A2.2 JTREE) (A2.0 (A1.2 A2.2 A3.2)) 25"
(INSIDE '(L 3) LTREE) ((B 1) ((E 2) ((K 3) (L 3))) 3 (SUPERLIST "I LTREE) (CI 3) (J 3)) blt-
(SUPERLIST • A2.0 3TREE) ((A1.0 (A1.1 A2.1 A3.1)) (A2.0 (A1.2 A2.2 A3.2)) (A3.0 (AI .3 A2.3 A3.3))) fc5-
6.1
193 Wie wir gerade im Beispiel demonstriert haben, erhalten wir SUPERLIST durch den geschachtelten Aufruf von SUBLIST.
51 Man vergleiche wieder die Ergebnisse der folgenden Test-Beispiele mit der Definition von SUPERLIST, sowie den Beispielen und Definitionen von SUBLIST und INSIDE ! Um für die zu definierenden Frage-Funktionen reproduzierbare Test-Ergebnisse zu erhalten, wurde der "Tracer" der ersten beiden Befehle vom Test-Lauf aus Abs. 5.1 gespeichert: TRACER-1.1 enthält den "Trace" des ersten Befehls (PUT-ON 'BLOCK-B 'BLOCK-C) ; TRACER—1.2 zusätzlich den "Trace" des zweiten Befehls (PUT-ON 'PYRAMID 'BLOCK-C) als zweites top-level Element der Liste. Mittels PRINTDEF1 geben wir beide "Tracer"-Versionen strukturiert aus. 67 Für die später folgenden Tests der Frage-Funktionen laden wir TRACER-1.2 auf TRACER. Wir wollen nun die Funktionen INSIDE, SUBLIST und SUPERLIST auf TRACER-1.1 und TRACER-1.2 anwenden, um das Verhalten dieser Funktionen am konkreten Beispiel zu verstehen: Diese Funktionen sind Grundlage der anschließend zu definierenden Frage-Funktionen, die über der Liste TRACER arbeiten ! Um übersichtliche Ausdrucke zu erhalten, betten wir hier die Funktionsaufrufe in PRINTDEF1 ein. 69 Vergleichen wir nochmals die Definitionen: INSIDE liefert das top-level Element der Liste, in dem das Argument vorkommt: Im ersten Beispiel das erste, im zweiten Beispiel das zweite top-level Element von TRACER-1.2 . Wird nichts gefunden, so ist das Ergebnis NIL. 70 Das Ergebnis von SUBLIST ist die "Sub-Liste", in der das Argument top-level Element ist.
6.1
(Ii.) (OUT ) (OUT) (H'l ) (out)
(PRINTDEM TRACER-1 .1 )
((MOVE-OBJECT (6 1 2)))
(CUT 1 (Ol T)
(OUT )
2))
BLOCK-B)
((GET-RID-OF BLOCK-A) ((PUT-AT BLOCK-A (1 5
(OUT ) (OUT ) (PUT) (OUT )
OUT) (OUT ) (OUT) (0) T)
BLOCK-B
((PUT-AT
(6 1 2)))
BLOCK-B>
TRACER-1.2)
O ((oUT i; T) ) N 6 9 ((IV) ClT ' ) (PRINT DE F1 (INSIDE (M 'OA E -S PACE B LOCK -C PYRAMD I ) TRACER-12.) ) ((C U TT ) ) 71 0))) ((('OIlT ' T) ) (PU(U T A T P A M D I 2)) ( G R A S P P Y R A M I D ) a(Mi.TT ) ) (MOVE-OBJECT (61 2))) I* (Ol;l,TT) NIL (UNGRASP PYRAMD 70(OliT ) ( IT •• ) (PR(IP NU TT D-A EFT1 B(SLU BK LA T (1('PU AT BLOCK - SO)) TRACER-11.) ) (1A (Ol ' ;) O C -IS-A 5T-0)) (M I ) (G R A S P B L O C K ) (OllT ' )) ((U MN O V -O 5)) 0))) (Cl T G REA SB PJECBTLO(1 CK-A ((LT) N I L ((011) OlT ' ) 71 NU TT D-A EFT1 B(SLU B L-B IST (b('PU -B 1 2)) TRACER-1.1) ) .IM )T) (PR(IP (((O U O C K 1T-A 2))T 8L0CKit O U T ) < ( G R A S P B L O C K B ) (OUT) (C((L EEATR-R -TIOP BL O CK -B )OCK-A) OU T ) G D O F B L ((OU (.PI(G UR TA -AST LLO CC KK A - -A)(1 5 0)) T P-OBB B O ((O U T))) O U T ( M O V E J E C T (1 (UEN G R A ST PB LOC KA -2))) >S 0))) (OUT) ((U MN O V O B J E C (6 1 ((OO U T ) GRASP BLOCKB - )) ) UT T)) ((O OU U N I L (OUT T)) 72(( 0INl )T )(PR(G INRTA 0E F1 8L(S0U B L-A IST (G ' RASP BLOCKT-A R)ACER-1 .1 ) ) S P C K ) ((O C T ) NIL T (CU OT l') ) 73CS) (PRINTDEF1 (SUPERLIST '( PUT-AT BLO ACK (1- 5 0)) TRACER-11.) ) (cni OU T))
(CUT) (OUT) (tin ) (OUT) (0!'T) (CUT ) (II.) ( o n )
(OUT )
( OUT )
(OCT ) (OI'T ) (OUT) (OI'T ) (OUT) (M'T ) (OUT) (OUT ) ( CUT ) (IN) (OUT) (OUT) (OUT ) (IN) ( OUT ) (OUT ) (CUT ) (IN)
(OUT) (CIJT) (OUT ) (OUT) (OUT) (OUT) (mil) (CUT ) (OUT) (OUT) (OI'T )
(PR1NTDEF1 (SUPERLIST '(PUT-ON BLOCK-B
((MOVE-OBJECT (6 1 2 ) ) ) ((UNGRASP BLOCK-B> NIL 75-
(PP*
BLOCK-O
TRACER-1.1)
DID-TEST)
)
(OUT) (IN)
(HOU-TEST
(OUT)
((GRASP 88-
(OUT )
1
CPUT-AT
BLOCK-B)
BLOCK-B
(b
(MOVE-OBJECT
(Cl'T) (1'.) (Ol'T)
(HOW-TEST " 7 "
(CUT)
90-
(Ol: I )
"(GRASP
BLOCK-A)
)
1
2))
tfcl
) 2))
200
6.1
6.1
201 Die Antwort-Liste kann mittels MAPCAR aus LT zusammengestellt werden !
86 Die Beispiele zeigen im Vergleich mit dem TRACER-1.1 , daß die Funktion HOW-TEST wie erwartet
arbeitet.
91 Die Frage-Funktion WHY-TEST ("Warum hast Du ... ?") soll als Antwort den zur Frage übergeordneten Knoten finden. Zuerst müssen wir mit INSIDE prüfen, ob die erfragte Handlung im TRACER zu finden ist und binden das Ergebnis an LT. Ist LT leer, so ist die Antwort NIL. Andernfalls übergeben wir die Liste LT an SUPERLIST und speichern das Ergebnis wiederum auf LT. Ist
jetzt
LT leer, so gibt es keinen übergeordneten Knoten. Die Antwort soll in diesem Fall sein: "BECAUSE YOU TOLD ME TO DO IT". Ist LT nicht leer, so ist das erste Element von LT der gesuchte top-level Knoten und wird als Antwort
zurück-
gegeben. Das zusätzliche LIST sorgt wieder dafür, daß die Ausgabe-Form mit den anderen übereinstimmt ! 92 Die folgenden Beispiele liefern die richtigen Resultate, wie der Vergleich mit TRACER-1.1
bestätigt.
202 6.2 Definition der erweiterten Frage-Funktionen mit "Spezifizierung" und "Fokussierung" des Dialogs
In diesem Abschnitt wollen wir die Frage-Funktionen so erweitern, daß ein zweites, spezifizierendes Argument angegeben werden kann. Betrachten wir als Beispiel wieder TRACER-1.2 : In beiden top-level Elementen kommt (GRASP BLOCK-B) vor, aber in jeweils anderem Kontext. In ihrer jetzigen Form greifen die Frage-Funktionen immer von links beginnend auf den TRACER zu und beziehen sich im Ergebnis auf das erste top-level Element, in dem zum ersten Mal das Argument gefunden wird. Durch ein zweites Argument sollte im natürlichen Sprachgebrauch auch
(wie
!) der Zugriff spe-
zifiziert werden können. 3
Wir binden an TEST eine Liste, die aus drei
top-level
Elementen besteht: Im ersten kommt ALPHA, im zweiten BETA und im dritten ALPHA und BETA vor. 6
Die Hilfsfunktion INSID2 soll die beiden S-Expressions SEX1 und SEX2 in der Liste L suchen. Ergebnis ist das top-level Element von L in dem SEX1 und SEX2 enthalten sind, oder NIL sonst. INSID2 wird rekursiv definiert. Die Endbedingung ist in der 1. Klausel, die Test-Bedingung
(mittels AND ver-
knüpfte INSIDE-Aufrufe) in der 2. Klausel
formuliert.
Trifft sie für das erste top-level Element von L nicht zu, so wird in der 3. Klausel INSID2 rekursiv auf die Restliste 7
angesetzt.
Die drei Beispiele zeigen, daß die Funktion wie gewünscht arbeitet. Als zusätzliche Erweiterung der Frage-Funktionen
soll
es möglich sein (wie im natürlichen Sprachgebrauch
'),
auf die vorangegangene Antwort bezug zu nehmen: Ist ein
6.2
203
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT > ( IN) (OUT) (OUT)
00 X
$R Z P . L I SP P500 LOADING SIEMENS-INTERLISP
...... GOOD
RESET
(IN) (OUT) (OUT) (OUT) (OUT) (OUT ) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) ( IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) ( IN ) (OUT) (OUT) (OUT)
VERSION
4.0
•»•«•«
AFTERNOON.
1(DATE) "13-JUN-81 2-
13:51:06"
LOAD(BLOCKS-UORLD) PR E T T Y D E F F O R M A T FILENAME:
(OUT) (OUT) ( OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT ) ( IN) (OUT) (OUT ) (OUT) ( IN) (OUT) (OUT)
-
BLOCKS-WORLD
CREATED
13-JUN-81
13:36:45
LISP-DATA.BLOCKS-WORLD.72
BLOCKS-HORLDCOMS (FIRSTCOL RESET) BL O C X S - W O R L D 3(SET8 TEST ((A ( A L P H A 4-
•( ( A ( A L PHA 1 ) ) ( 6 ( 2 B E T A ) ) ( C ( A L P H A 1 ) ) (B (2 B E T A ) ) (C ( A L P H A B E T » ) ) )
(INSIDE "ALPHA (A ( A L P H A 1 ) ) 5( I N S I D E 'BETA (B (2 B E T A ) )
TEST)
TEST)
6 -
> (INSIDE S E X 2 (CAR L)>) (CAR L)Ì (T ( I N S I D Z SEX 1 S E X * ( C D R L > > (INSID2) 7( I N S I D 2 "ALPHA "BETA (C ( A L P H A B E T A ) ) 8( I N S I D 2 'C " B E T A (C ( A L P H A B E T A ) ) 9(INS ID 2 NI L 10-
"A
'B
TEST)
TEST)
TEST)
BETA))
) )
6.2
20k
(IN)
G ETO(D HOP)
( OUT )
(LAMBDA
( OUT) (OUT)
(SETQ
NIL
(•
EDITED:
RESERVATIONS
"12-JUN-81
NIL)
(S ETQ
22:22:49")
TRACER
NIL)
(SETS
(SETQ
PLAN
MEMORY
NIL) NIL))
1 1 -
(OUT ) ( IN)
(SETQ
(OUT)
(TRACER
(IN)
(PP *
TRACER
TRACER-1.2)
RESET)
DID)
(OUT ) (OUT) (OUT)
< D I D
(OUT)
(DID)
( OUT)
13-
L1
MEMORY) FOCUS))
(OUT) (IN) (OUT) (OUT)
(DID) 14-
(OUT) (IN)
(Dl D
(OUT)
NIL
(OUT)
15-
'(GRASP
SPHERE)
'(GRASP
BLOCK-B)
)
(OUT) (IN)
(DID
(OUT)
"YES" 16-
(OUT)
'(GRASP
PYRAMID)
)
(OUT ) (IN)
(CAR
(OUT)
(GRASP
(OUT)
17-
MEMORY) BLOCK-B)
(OUT) (IN)
( C DR
(OUT)
((PUT-ON
(OUT)
((UNGRASP
(OUT)
18-
MEMORY) PYRAMID
BLOCK-C)
PYRAMID))))
(OUT) (IN)
(DID
(OUT)
"YES"
(OUT)
19-
(OUT)
'(UNGRASP
BLOCK-B)
>
((MAKE-SPACE
BLOCK-C
PYRAMID)
!)
6.2
205 top-level Element des TRACER (ggf. durch ein spezifizierendes Argument)
"in den Fokus des Dialogs"
ge-
bracht worden, so sollen in den folgenden Fragen die spezifizierenden Argumente weggelassen werden dürfen. Darüber hinaus sollte auch auf das erste Argument verzichtet werden können, wenn sich die Frage auf die vorangegangene Antwort bezieht. Diesen Komfort erreichen wir durch Einrichtung eines globalen MEMORY, der die vorangegangene Antwort und den "Fokus" speichert. Zweckmäßig lassen wir MEMORY von DROP löschen und ergänzen die Funktion entsprechend. 11 Für die folgenden Tests laden wir uns TRACER-1.2 auf TRACER
zurück.
Nun zur Definition der Frage-Funktion DID ("Hast Du ... ?"), der erweiterten Version von DID-TEST. FrageParameter sind L1 und L2 zur Spezifizierung. Mindestens L1 muß gegeben sein, sonst ist die Frage sinnlos : In diesem Fall (1. Klausel) wird "?" ausgedruckt. Sind zwei Argumente gegeben (3. Klausel), so wird der FOCUS durch INSID2 ermittelt. Ist nur ein Argument gegeben (2. Klausel), so wird zuerst versucht, ob INSIDE im FOCUS (das ist der CDR des MEMORY, wie wir gleich sehen werden
!) fündig wird.
Wenn ja, wird der alte FOCUS geladen, somit bleibt der Dialog "beim Thema"
!
Falls im alten FOCUS nichts zu
finden ist, wird der neue FOCUS durch INSIDE aus dem TRACER
ermittelt.
Im zweiten COND wird geprüft, ob FOCUS leer ist; wenn ja, ist die Antwort NIL. Andernfalls wird der MEMORY mit L1 und dem FOCUS geladen; die Antwort ist "YES". 13 Die folgenden Test-Beispiele zeigen das Verhalten der Frage-Funktion DID und den zugeordneten Inhalt des MEMORY s Durch den Lade-Modus enthält der CAR das erste
20 6
6.2
(IN) (OUT)
(CDR M E M O R Y ) ((PUT-ON PYRAMID
(OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) ( IN) (OUT)
((UNGRASP ¿0-
(OUT) (OUT) (OUT) ( IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(DID ' ( C L E A R - T O P "TESZ1 (C DR M E M O R Y ) ((PUT-ON BLOCK-B ((UNGRASP
11-
(PP*
((MAKE-SPACE
BLOCK-C
PYRAMID)
BLOCK-B)
)
BLOCK-C)
((PUT-AT
BLOCK-B
(6 1 2 ) )
BLOCK-B))))
WHEN)
((UNGRAS P BLOCK-B)))) 44-
(IN) (OUT)
( CD R M E M O R Y )
(WHAT)
(WHAT BLOCK 7-
-BLOCK-A)
(WHAT RED 8-
'BLOCK-D
'COLOR)
PROPERTY=TYPE)
7.
218
( I' ) i• T ) (l'I T ) ( r. 1 T ) CUT) ( n I) (im i ; C«:T> CV7 ) (CI T )
(MAP2CAR ( S E T NEW
(PIT) (our) ( Cl T >
(GRASPING 17-
(I") (OUT )
2BL0CK-A ( D I R E C T L Y - S U P P O R T S N I L COLOR GREEN P L A C E ( 1 1 S U P P O R T E D - B Y B L O C K - B SUPPORTP T T Y P E B L O C K )
NIL
POSITION
(2
S
HAND)
2 OLD> 2B0X
OLD)
( ( D I R E C T L Y - S U P P O R T S N I L COLOR GREEN P L A C E ( 1 S U P P O R T E D - B Y B L O C K - B SUPPORTP T T Y P E B L O C K )
(IN) (CUT ) (OUT) (OUT) (CUT) (OUT ) (OUT) (UM ) ( OUT ) (OUT) ( (U. T ) (OUT) (OUT ) (OUT) ( UU1 ) (CI T ) ( Ol'l ) (OUT)
TABLE
( S E T Q N E U S T A T E (MAPCAR S T A T E • ( L A M B D A ( O L D )
P R O P E R T I E S VON S T A T E AUF N E W S T A T E ) (QUOTE (LAMBDA (NEW O L D ) ( S E T NEW (COPY ( G E T P R O P L I S T O L D >
7.2
227
(II,) (CI (Oll) (OUT) ((•CT) (Ct'l) (CM) (OUT) (I-IT ) (C1T) (C(:T) (,U>T) (OCT) (rei) (f.MT) (;l'T) (PIT) (ri.il) (OCT) ( f. I T) (UT) iC I T )
X)
( !f ) (OlT) ("CT) U.l'T ) ( ir, ) (CHT) ( OCT ) (OLT ) ( II ) Ol.-T) (OCT) (II. ) (OCT ; (OCT) ( llO (OIT)
(PP*
RESET-SITUATION)
FU1 S1 (DE FU2 52-
F U 2 ( ) ( P R 1 N T " F U 2 . . . " ) ( F U 3 ) ( P R I N T " . . . FU2-)>
(06 FU3()(PR INT"FU3 . . . " ) ( F U 4 ) ( P R I N T " FU3 53(DE FU4 54 -
FU4(>(PRINT"FU4
(FUO) "FUO..." "FU1..." "FU2..." "FU3 " •FU4" "...FU3" "...FU2" "...FU1" "...FUO" T 55 -
FU3-)>
COLOR
PYRAMID
BLUE BLACK
7.2
231
(IN) COUT ) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT ) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT ) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT)
(HE F U « ( ) ( R E T F R O M (FU4 R E D E F I N E D ) FU4 5b _ (SETQ FU1 57.
RETURN-LABEL
RETURN-LABEL
(PRINT"FU4")>
'FU1)
( F UO ) "FUO..." "FU1..." " F U 2 .. ." "FU3..." " FU«" .FUO" T 58. (SETQ R E T U R N - L A B E L *FU2) (RETURN-LABEL RESET) FU? 5?. ( FUO) "FUO..." "FU1..." "FU2..." "FU3..." "FU4" "...FU1" " . .. F U O " T feO-
GETD(RESET-BLOCKS-WORLD) ( L A M B D A N I L (• E D I T E D : " I O - A U 6 - 8 1 1 2 : 4 6 : 3 4 " ) (DROP) (PUTPROP (QUOTE HAND) (QUOTE GRASPING) HAND-GRASPING) (PUTPROP (QUOTE HAND) (QUOTE POSITION) H A N D - P O S I T I O N ) ( P R O G (BW T I T V ) ( S E T « TI T O Y - I N D I C A T O R ) L O O P 1 « C O N D ( ( N U L L T I ) ( S E T Q S I T - C O U N T E R 0) ( S A V E - S I T U A T I O N 0 ) ( R E T U R N T ) ) > ( S E T Q B U B W - O B J E C T S ) ( S E T Q TV ( E V A L ( C A R T I ) ) > L 0 0 P 2 ( C O N D ( ( N U L L B W ) (GO L 0 0 P 3 ) ) ) ( P U T P R O P (CAR BU) (CAR ( S E T Q TV (C D R T V ) ) (GO (GO L 0 0 P 1 ) ) )
TI) (CAR TV)) (SETQ BU (COR B U ) ) L 0 0 P 2 ) L O O P S (SETQ TI (CDR TI))
70. GETD(REPORT/UINSTON) ( L A M B D A ( M E S S A G E ) (« E D I T E D : " 1 0 - A U G - 8 1 1 1 : 2 4 : 0 5 " ) (PROG (INPUT) (PRINT M E S S A G E ) LOOP (SETQ INPUT (READ)) (CONO ((AND (NOT (ATOM I N P U T ) ) ( E Q U A L (CAR I N P U T ) (QUOTE R E P O R T ) ) ) (RETURN (EVAL (CADR I N P U T ) ) ) ) (T ( P R I N T ( E V A L I N P U T ) ) ) ) (GO L O O P ) ) ) 71.
7.2
2 3 2
(IN) (OUT) COUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT ) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT ) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT ) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT ) (OUT) (OUT) (IN) (OUT) (OUT) (OUT)
(PP
REPORT)
(REPORT) 72. (PP
MESSAGE)))
BU-TRACER)
(BU-TRACER) 73.
BW-FUNCTION>
(RESET-BLOCKS-WORLD) T 74(BW-TRACER 1 "O.K." 75.
(PUT-ON
'BLOCK-B
'BLOCK-C)
)
( B W - T R A C E R ( P U T - A T ' B L O C K - A "(4 3 2)) ) (PUT-AT — C A N N O T F I N D S P A C E FOR OR S U P P O R T «««RESET-SITUATION-1««« T 76. (BU-TRACER 2 "O.K." 77.
(PUT-ON
'BLOCK-A
'BLOCK-B)
)
FOR
THE
OBJECT)
7.2
233
(IN) (OUT ) (OUT) (IN) (OUT ) (OUT ) (IN) (OUT) (OUT) (OUT) (OUT) (IN ) (OUT) (OUT) (IN) (OUT) (OUT ) (OUT ) (IN ) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) ( IN) (OUT) (OUT) (OUT ) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(IN) (OUT) (OUT) (OUT) (IN)
(BU-TRACER-ON) "BW-TRACER-ON..." (PUT-ON 'PYRAMID 3 "O.K."
'BLOCK-A)
(PUT-ON 'BLOCK-C 'SPHERE) (MAKE-SPACE — NO S P A C E B U T N O •«•RESET-SITUATION-3«»» T (PUT-ON 'BLOCK-D 4 "O.K."
CLUTTER
EITHER)
'BLOCK-C)
(BU-TRACER-OFF) " BW-TRACER-OFF" 78. (BW-PLAN) ( ( M O V E T O (1 1 4 ) ) ( G R A S P B L O C K - A ) ( M O V E T O (8 1 2 ) ) ( U N G R A S P B L O C K - A ) ( M O V E T O (1 1 2>> ( G R A S P B L O C K - B ) ( M O V E T O (6 1 4)) ( U N G R A S P B L O C K - B ) ( M O V E T O (8 1 2 ) ) ( G R A S P B L O C K - A ) ( M O V E T O (6 1 6 > ) ( U N G R A S P B L O C K - A ) ( M O V E T O (3 8 2 ) ) ( G R A S P P Y R A M I D ) ( M O V E T O (6 1 8 ) ) ( U N G R A S P P Y R A M I D ) ( G R A S P P Y R A M I D ) ( M O V E T O (2 8 2)) ( U N G R A S P P Y R A M I D ) ( M O V E T O (6 1 6 ) ) ( G R A S P B L O C K - A ) ( M O V E T O (7 5 2 ) ) ( U N G R A S P B L O C K - A ) ( M O V E T O (6 1 4 ) ) ( G R A S P B L O C K - B ) ( M O V E T O (4 1 2 ) ) ( U N G R A S P B L O C K - B ) ( M O V E T O (9 4 2 ) ) ( G R A S P B L O C K - D ) ( M O V E T O (6 1 4 ) ) (UNGRASP BLOCK-D)) 7?. TRACER ( ( ( P U T - O N B L O C K - B B L O C K - C ) ( ( P U T - A T B L O C K - B (6 1 2 ) ) ((GRASP BLOCK-B) ((CLEAR-TOP BLOCK-B) ((GET-RID-OF BLOCK-A) ( ( P U T - A T B L O C K - A (8 1 0 ) ) ( ( G R A S P B L O C K - A ) ) ( ( M O V E - O B J E C T (8 1 0 ) ) ) ( ( U N G R A S P B L O C K - A ) ) ) > ) ) ( C M O V E - O B J E C T (6 1 2 ) ) ) ( ( U N G R A S P B L O C K - B ) ) ) ) ( ( P U T - O N B L O C K - A B L O C K - B ) ( ( P U T - A T B L O C K - A (6 1 4 ) ) ( ( G R A S P B L O C K - A ) ) » ( M O V E - O B J E C T (6 1 4 ) ) ) ( ( U N G R A S P B L O C K - A ) ) ) ) ( ( P U T - O N P Y R A M I D B L O C K - A ) ( ( P U T - A T P Y R A M I D (6 1 6 ) ) ( ( G R A S P P Y R A M I D ) ) ( ( M O V E - O B J E C T (6 1 6 ) ) ) ( ( U N G R A S P P Y R A M I D ) ) ) ) ((PUT-ON BLOCK-D BLOCK-C) ((MAKE-SPACE BLOCK-C BLOCK-D) ( ( G E T - R I D - O F B L O C K - B ) ( ( P U T - A T B L O C K - B C4 1 0 ) ) ( ( G R A S P B L O C K - B ) ((CLEAR-TOP BLOCK-B) ((GET-RID-OF BLOCK-A) ( ( P U T - A T B L O C K - A (7 5 0 ) ) ( ( G R A S P B L O C K - A ) ( ( C L E A R - T O P B L O C K - A ) ( ( G E T - R I D - O F P Y R A M I D ) ( ( P U T - A T P Y R A M I D (2 8 0 ) ) ( ( G R A S P P Y R A M I D ) ) ( ( M O V E - O B J E C T (2 8 0 ) ) ) ( ( U N G R A S P P Y R A M I D ) ) ) ) ) ) ( ( M O V E - O B J E C T (7 5 0 ) ) ) ( ( U N G R A S P B L O C K - A ) ) ) ) ) ) ( ( M O V E - O B J E C T (4 1 0 ) > ) ( ( U N G R A S P B L O C K - B ) ) ) ) ) ( ( P U T - A T B L O C K - D (6 1 2 ) ) ( ( G R A S P B L O C K - D ) ) ( ( M O V E - O B J E C T (6 1 2 ) ) ) ( ( U N G R A S P B L O C K - D ) ) ) » ) 80.
(DATE) "12-AUG-81 18. (EXIT)
0 2:57:1 2"
23k
7.2
5 6 Zuerst setzen wir RETURN-LABEL auf FU_1_ . Wenn wir FUO aufrufen, sehen wir, daß nach dem Ausdruck "FU4" in FUO zurückgesprungen wird. Setzen wir RETURN-LABEL auf FU2 ,
so wird in FU_1_ zurückgesprungen.
Nach diesen Vorübungen nun die Erweiterung der "BlockWelt" zum automatischen Retten und Rückladen: 60 Im Update von RESET-BLOCKS-WORLD wird vor dem RETURN die globale Variable SIT-COUNTER auf Null gesetzt und diese Situation mittels SAVE-SITUATION
gespeichert.
70 Tritt im z.Z. definierten "Block-Welt"-System ein Anwendungsfehler auf, so wird REPORT aktiviert und das System geht in eine Read-Eval-Print Schleife. Für das automatische Rückladen bei Anwendungsfehlern muß REPORT geändert werden. Da die Original-Version als wertvolles experimentelles Instrument für den Nicht-AutomatikModus erhalten bleiben soll, wird sie umbenannt und ist künftig unter dem Namen REPORT/WINSTON
verfügbar.
Die neue Version von REPORT arbeitet mit der neuen Version v o n
BW-TRACER
über globale Variable
("Flags")
zusammen: TRACER-MODE , RESET-BW-FLAG und RETURN-LABEL werden von BW-TRACER initialisiert. Ist TRACER-MODE ungleich NIL, so wird das RESET-BW-FLAG auf T gesetzt und REPORT mittels RETFROM verlassen (nachdem die Meldung ausgedruckt wurde). Ist TRACER-MODE gleich NIL, so wird die alte REPORT-Version, REPORT/WINSTON ,
angesprochen.
72 BW-TRACER , die "kleine Funktion" aus Abschnitt 5.2 ist nicht mehr wiederzuerkennen: Zuerst müssen die Flags gesetzt und erst dann darf unser "bekanntes"
Statement
zur Bindung des TRACER angesprochen werden. Damit diese Reihenfolge eingehalten wird, muß BW-TRACER als NLAMBDAFunktion definiert werden
!
Im "bekannten"
Statement
muß darum jetzt EVAL stehen. Trat kein Fehler auf, so ist RESET-BW-FLAG nicht von REPORT gesetzt worden; BW-TRACER wird ab SAVE-LABEL
2
235 fortgesetzt s Das Flag TRACER-MODE wird gelöscht, die globale Variable SIT-COUNTER um 1 erhöht, diese Situation mittels SAVE-SITUATION gerettet und eine entsprechende Meldung ausgegeben. Trat dagegen ein Fehler auf, so wurde RESET-BW-FLAG von REPORT gesetzt, BW-TRACER springt zu RESET-LABEL s TRACER-MODE und RESET-BW-FLAG werden gelöscht, mittels RESET-SITUATION wird die letzte Situation zurückgeladen und eine entsprechende Meldung gedruckt. Die folgende Test-Serie zeigt das Verhalten der erweiterten "Block-Welt" s Anwendungsfehler werden erkannt, die REPORT-Meldung gedruckt und das automatische Rückladen in die letzte gültige Situation initialisiert. Wie im ersten Teil dieses Abschnitts gezeigt wurde, ist jede fehlerfreie Situation mit allen ihren Bindungen
verfügbar. In PLAN und TRACER wurden die Fehler nicht übernommen; der "richtige" Weg ist nahtlos dokumentiert.
236 7.3 Einfache Funktionen zur Definition von Oberbegriffen Im letzten Abschnitt dieses Kapitels wollen wir die "Block-Welt" dazu bringen, "durch Nachahmung etwas zu lernen". Es ist eine Vorübung zu dem im Merkblatt vorgeschlagenen Lern-Programm. Obwohl wir nur einfachste Funktionen definieren, werden doch zwei wesentliche Aspekte deutlich : Die Ambivalenz zwischen Datum und Programm in LISP ermöglicht einfache Programm-Strukturen. Die "Block-Welt" kann ohne spezifizierte, eingebaute Programmierung neue Information aufnehmen und verarbeiten ; sie wird zum "Offenen System" ! Wenn wir einen Befehl geben, z.B. (PUT-ON 'BLOCK-B 'BLOCK-C) so wird ein TRACER aufgebaut: ((PUT-ON BLOCK-B BLOCK-C) ... ) Wollen wir ein Element des TRACER als Befehl interpretieren, so fehlen uns noch die "quote"-Zeichen. 3
Setzen wir vereinfachend voraus, daß hier zum Test nur die "allgemeingültigen" PUT-ON Befehle benutzt werden, so ist die einfachste Lösung die Umgehung dieses Problems: Wir sorgen mittels SETQs dafür, daß BLOCK-A zu BLOCK-A ,
... und TABLE zu TABLE evaluieren, dann kön-
nen wir hier stets die quote-Zeichen weglassen ! k
Mit Hilfe der Funktion PLAY sollen mehrere Befehle nacheinander bearbeitet werden. PLAY wird als rekursive no-spread Funktion definiert. Ist die Befehlsliste L abgearbeitet, wird "O.K." ausgegeben. Andernfalls wird der nächste Befehl der Funktion BW-TRACER übergeben. Damit ist sichergestellt, daß ein TRACER angelegt wird
.3
237
( p.) (OUT)
DO %
ÎRIP.LISP PSOO LOADING
(OUT) (OUT) (OUT) (OUT)
SIEMENS-INTERLISP
-
VERSION
4.0
(OUT) (OUT) (CUT) (OUT ) (OUT) (CUT) ( OUT ) (IN) (CUT) (OUT) (OUT) (I'J) (OUT) (OUT ) (OUT) (OUT) (OUT) (OUT)
.«.«*. GOOD
RESET
MORNING.
1 " (DATE) "29-SEP-81 2-
09:50:56"
LOAD(BLOCKS-UORLD) PRETTYDEF
FORMAT
FILENAME:
L ISP.DATA.BLOCKS-WORLD . 84
BLOCKS-WORLD
CREATED
28-SEP-81
BLOCKS-WORLDCOMS (FIRSTCOL RESET) BLOCKS-WORLD 3-
(OUT ) (IN) (OUT) (OUT ) (OUT)
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN ) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(SETQ BLOCK-A BLOCK-A
(PP
PLAY)
< P L AY (LAMBDA L »«COMMENT«» (COND ((NULL L) (QUOTE "O.K.")) (T (BU-TRACER (EVAL (CARL))) (APPLY (QUOTE PLAY) (COR L » (PLAY)
11(PP
THAT-IS)
CTHAT-IS > (THAT- IS) 13-
CIN ) (OUT)
(PP
(OUT)
((GRASP PYRAMID)) ((MOVE-OBJ ECT (1 3 2))) ((UNGRASP PYRAMID))))) (OUT) 17" (OUT) (IN) (T HAT- IS 'HOUSED (OUT ) "O.K." (CUT) 18(OUT) (IN) H0USE1 (OUT) ((PUT-ON BLOCK-A TABLE) (PUT-ON PYRAMID BLOCK-A)) (CUT) 1?" (OUT ) (IN) ( DROP) (OUT) NIL (OUT ) IO(OUT) (IN) (PLAY 1(PUT-ON BLOCK-D TABLE) '(PUT-ON BLOCK-B SPHERE) •(PUT-ON BLOCK-C BLOCK-D) '(PUT-ON BLOCK-B BLOCK-C) ) 5 (MAKE-SPACE -- NO SPACE Bur WO CLUTTER EITHER) (OUT) (OUT ) *« » RESET-SITUATI ON-3*** 1, 5 "O.K." (OUT) M(OUT) (OUT) (IN) TRACER (OUT) ( ( (PUT-ON BLOCK-D TABLE) ((PUT-AT BLOCK-D (3 8 0)) ((GRASP BLOCK-D)) ((MOVE-OBJECT (3 8 0))) ((UNGRASP BLOCK-D))>) (OUT) ((PUT-ON BLOCK-C BLOCK-D) ((PUT-AT BLOCK-C (3 8 2)> ((GRASP BLOCK-C)) ((M0VE-OBJ ECT (3 8 2))) ((UNGRASP BLOCK-C)))) (OUT ) ((PUT-ON BLOCK-B BLOCK-C) I(PUT-AT BLOCK-B (3 8 4)) ((GRASP BLOCK-B)) ((MOVE-OBJECT (3 8 4))) ((UNGRASP BLOCK-B)))>> ( OUT) 21(CUT) (IN) (THAT-IS 'T0WER4) (OUT) "O.K." (OLD 23(OUT) ( n ) T0WER4 ((PUT-ON BLOCK-D TABLE) (PUT-ON BLOCK-C BLOCK-D) (OUT) (PUT-ON BLOCK-B BLOCK-C)) (OUT) 24(OUT ) (IN) ( RESET-BLOCKS-WORLD ) (OUT) T (Ol T ) 25(OUT) (IN) (BUILD 'HOUSED (OUT) 1 2 "O.K." ( OUT) 26(OUT ) (IN) (BUIL D1T0WER4) ( PUT) 3 4 5 "O.K." (OUT) Z7(OUT)
7.3
239
(BW-PLAN) ( ( M 0 V E TO (MOVETO
(1
1 4))
(GRASP
)
(MOVETO
(6
1
2))
(MOVETO
(1
1
2))
(GRASP
(GRASP
BLOCK-A)
(MOVETO
(1
PYRAMID)
(MOVETO
(1
(GRASP
BLOCK-D)
(MOVETO
(GRASP
BLOCK-C)
(MOVETO
BLOCK-B)
(MOVETO
8
2))
(UNGRASP
BL O C K - A )
8
4))
(UNGRASP
PYRAMID)
(5
8
2))
(UNGRASP
BLOCK-C)
(5
8
4))
(UNGRASP
BLOCK-C)
(5
8
6))
(UNGRASP
BLOCK-B))
28(PRINTDEF1 TRACER) « ( P U T - O N BLOCK-A TABLE) U P U T - A T B L O C K - A (1 8 0 ) ) ((GRASP BLOCK-A)) ( ( M O V E - O B J E C T (1 8 0 ) ) ) ((UNGRASP BLOCK-A> > (INITIALIZE) 9(PP STABC)
(STABC) 10(PP STPKT)
(STPKT) 11-
8.
252
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(PP STATUS) X 14-
••COMMENT«« 0) 0) (LIST MAXLINE MAXCOL>>
W=WHITE—> 0 »
(PP PLAY-GO)
(PLAY-GO) 15-
8. 5
253 Da wir auch mit kleineren (und auch nicht-quadratischen) Spielfeldern arbeiten wollen (z.B. zum Nachspielen von GO-Problemen), wird die aktuelle Feldgröße in den globalen Variablen MAXLINE (für die Anzahl der Zeilen) und MAXCOL (für die Anzahl der Spalten) gespeichert.
7
Nach Konvention erfolgt die Bezeichnung der Zeilen mit den Zahlen 1 ... 19 , die der Spalten mit den Buchstaben A ... T . Für die Druck-Ausgabe sind die Buchstaben in der globalen Liste COLNAME verfügbar.
8
Die Funktion INITIALIZE initialisiert das leere 19 x 19 Spielfeld, bindet es an den (globalen) Namen BOARD und druckt eine entsprechende Meldung zur Dokumentation.
9
Die Ausgabe des Spielfeldes erfolgt, wie wir schon gesehen haben, mittels STATUS . STATUS benutzt zwei Hilfsfunktionen : STABC druckt (oben und unten) die SpaltenNamen ( A B C
... ) und STPKT den aktuellen Inhalt
(nach
Initialisierung die Punkte). STATUS ordnet die Zeilen in absteigender Reihenfolge und die Zeilen-Nummern bündig zum Brettrand. (Nach Konvention wird die Koordinate A1 links unten gezeichnet.) 12 Für die Zählung der Gefangenen richten wir zwei globale Zähler ein : BCNT für den schwarzen (black count) und WCNT (white count) für den weißen Spieler. In der Liste MEMO sollen alle Züge protokolliert werden. Mit der Funktion DROP-GO löschen wir BCNT , WCNT und MEMO , wobei in MEMO die aktuelle Spielfeldgröße eingetragen wird. 1f+ Die Funktion PLAY-GO ruft INITIALIZE , DROP-GO und STATUS. Sie fügt dem Bild des Spielfeldes (mittels MESSAGE) den Hinweis an, wie die schwarzen und weißen Steine angezeigt werden. Wird PLAY-GO ohne Argument aufgerufen, so wird (wie oben demonstriert) ein 19 x 19 Spielfeld eingerichtet und gezeichnet. Dagegen bewirkt eine Argumentangabe
(z.B.
11), daß ein entsprechend kleines quadratisches Feld (z.B. 11 x 11) vorbereitet wird.
8.
25^
(IN) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT)
(OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT)
(SETQ MAXLINE 5) (MAXLINE RESET) 5 16(SETQ MAXCOL 7) (MAXCOL RESET) 7 17-
(STATUSI A B C D E F G 3
T 18-
A B C D E F G
3 2 1
COLA ((A . 1 ) (B . 2) (C . 3 ) (0 . > (COUNT-GO) 44-
262
8.
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUTI (OUT) (OUT) (OUT) (OUT) (OUT) (OUTI (OUT) (OUT) (OUT) (OUT) UN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(PP MEM1) > (MEM1) 4S(PP MEMO)
(MEMO) 46-
(MEMO I 1. 2. 3. T 47-
BLACK
WHITE
7 • 5 BOARD
B3 C2 C4 C3 02 04 E3 03 -C3 (BCNT* 1) (WCNT= 0)
8.
263
(IN) (OUT) (OUT) (OUT) (IN) (OUT)
RECORDS (AFG.l AFG.2 AFG.3 AFG.4 DEM.1 LSG.1 LSG.2 LSG.3) 48AFG.4 ( (• AFG.4 S BEGINNT UND TOETET W / D0E-A8B.41) (N 83 B2 C3 Cl 03 D2 Ol) (B A4 B4 B1 C4 D4 E4 E3 E2 El) 7 7) 49-
(OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(PP RECORDS) «RECORDS CLAMBOA NIL ••COMMENT" (SORT RECOROS)
T» (RECOROS) 501RECORDS) (• AFG. 1 W BEGINNT UND TOETET S / D0E-ABB.36) (• AFG. 2 W BEGINNT UND TOETET S / D0E-A8B.37) (• AFG. 3 M BEGINNT UNO TOETET S / D0E-ABB.3B) (• AFG. 4 S BEGINNT UNO TOETET W / 00E-ABB.41) (• DEH. 1 SCHEINSEKI / DUE-BL0.26) -ABB.36) E (• LSG. 1 ZU AFG.l W BEGINNU TNO TOETET S / DO -ABB.37) E (• LSG. 2 ZU AFG.2 W BEGINNU TNO TOETET S / DO (• LSG. 3 ZU AFG.3 W BEGINNU -ABB.38) TNO TOETET S / DO E T 51-
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(PLAY-RECORD LSG.3 7) UND TOETET S / DO -ABB.38) E (• LSG. 3 ZU AFG.3 M BEGINNT 7 A BC D E F G H I K L 5 . . • 4 . . • 3 . 0 00000000.3 2 . 0 XX X X X X X 0 . 2 1 . . 0X . 0. X 0 . . 1 A 8c D E F G H I K L T 5Z(MEMO) BLACK WHITE 11 • 5 BOARD 1. C2 02 E2 F2 G2 H2J2 82 B3 C3 D3 E3 F3 G3 H3 J3 K3 K2 2. 3. Cl 4. 01 5. J1 6. Hl 7. Fl (BCNT= 0) (WCNT= 0) T 53-
8.
26h
(IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
(PP SAVE-RECORD)
(PRINT "DEFINE HEADER-INFORMATION, FORM ... (• NAME INFO)") (SETQ HEADER (READ)) (COND ((NOT (AND (EQ (CAR HEADER) (QUOTE •)) (EQ (CAOR HEAOER) NAME))) (RETURN "ILL.HEADER ... SAVE-RECORD TERMINATED" ) ) ) (SET NAME (CONS HEADER MEMO)) (SETQ RECOROS (CONS NAME RECORDS)) (ADDTOFILE NAME (QUOTE PLAY-GO) (QUOTE VARS)) (MAKEFILE (QUOTE PLAY-GO)) (RETURN NAME>> (SAVE-RECORD) ss(PP» PLAY-RECORD)
)
(E(F(G))>
H)
)
CZ) W H )
)
9.3
289
()
'()
)
(MATCH NIL 6-
' ()
'(B
C)
>
( IN) (OUT) (OUT) (OUT) (IN)
(MATCH NIL 7-
' (B
C)
'()
)
(MATCH
•
(OL'T) (OUT)
T 8-
(IN)
(MATCH
(OUT) (OUT)
T
(OUT) (IN) (OUT) (OUT ) (OUT)
•
( IN) (OUT) (OUT) (OUT)
5-
( —)
'()
(OUT) (OUT) (OUT ) (OUT) (OUT) (OUT) (OIJT) (OUT) (OUT) (OUT)
)
(IN) (OUT) (OUT) (OUT)
(OUT) ( IN)
(MATCH
(OUT)
T
(OUT) (OUT) (IN) (OUT) (OUT)
9-
•A
'A
)
(OUT) (OUT)
(MATCH NIL 10-
• A
(OUT) ( IN)
(MATCH
'
(OUT ) (OUT )
T 11-
• (B
t
C)
*A
>
)
(OUT )
(MATCH T 1Z-
•&
'(B
(MATCH T
'—
C)
(OUT) (IN) (OUT ) (OUT ) ( OUT ) ( IN ) (OUT) (OUT) (OUT) (IN)
"A
)
15IMATCH T
•- -
'(B
C>
(OUT) (OUT)
15-
(IN) (Ol'T)
(TRACE
(IN)
(MATCH
" ( - - )
'A
MATCH)
' (B
4)
'(B
MATCH: PAT = (B SEX = (0
il C)
(OUT ) (OUT)
(OUT)
MATCH = = T
MATCH MATCH T 13 -
(MATCH
-
)
T
T
T
' ( — [ > >
'(B
PAT SEX
= =
( — D) (B C 0)
MATCH : PAT = D SEX = B MATCH = N I L MATCH = NIL
D)
MATCH : PAT ( - D) SEX (C 0) MATCH : PAT = (D) SEX = ( C D) MATCH: PAT
=
SEX
=
D C
MATCH
=
( OUT) (OUT)
MATCH
(OUT) (OUT) (OUT) (OUT)
MATCH : PAT = ( — SEX » (03
(OUT) (OUT) (OUT) (OUT) (OUT)
MATCH:
(OUT) (OUT) (OUT) (OUT) (OL'T) (OUT) (OUT)
C ()
MATCH :
(OUT) (OUT)
(OUT)
(»> S --) LIS) ((ALPHA BETA) GAMMA (DELTA EPSILON)) 2K-
(INSIDN '(-- (t &) --) LIS) (ALPHA (BETA GAMMA) DELTA) 35(INSIDM "(-- (&) —) LIS) NIL 36(PP SA Y1) )
((UNGRASP
BLOCK-A))))))
(OUT)
((MOVE-OBJECT
(6
1
2)))
((UNGRASP
BLOCK-B))))
(OUT) (CUT)
50-
(IN) (CUT)
(WHEN) ((PUT-ON
(OUT) (OUT) (IN)
51-
(OUT) (OUT) (PUT)
(IN)
(SAY
BLOCK-A
BLOCK-A
BLOCK-B
'SPHERE
5
(1
5
)
(DATE) "21 -JAN-82L
(OUT)
54-
(OUT) (EXIT)
0))
(PUT-ON
0))
BLOCK-C))
"?" 51-
(OUT)
(IN)
(1
15:38:30"
((GRASP
BLOCK-B
BLOCK-C)
297 9.h "Rekursive Paraphrasen" einiger Systemfunktionen
Rekursive Funktionsdefinitionen sind nicht nur elegant, sondern besitzen auch den Vorteil der Reduzierung des komplexen Problems auf seinen einfachsten Fall. Allerdings: "Es braucht Zeit und Praxis, um rekursiv denken zu lernen" (Weissman/We67/) . Wir wollen daher als Übung im letzten Abschnitt dieses Kapitels "Rekursive Paraphrasen" einiger Systemfunktionen programmieren. Um eine Überschreibung der vorhandenen Systemfunktionen zu vermeiden, werden wir die Namen der Funktionen mit dem Suffix -TEST versehen. Zum bequemen Nachschlagen ordnen wir die rekursiven Beispiel-Definitionen alphabetisch und stellen sie ans Ende dieses Kapitels. Folgende Regeln für das Schreiben rekursiver LISP-Funktionen werden empfohlen (/Ep79/, /Si76/, /We67/) : - Formuliere die Endbedingung Typische Endbedingungen sind für S-Expressions Atome, für Listen die leere Liste und für Zahlen die Werte 0 bzw. 1 - Formuliere den Rekursionsschritt Reduziere dabei den schwierigen Fall auf den nächst einfachen Fall vor der Endbedingung - Verbinde beides in einer COND-Anweisung Berücksichtige ggf. den Fehlerfall in der letzten COND-Klausel Die Test-Beispiele wurden unter Einbeziehung der schon verfügbaren Strukturen von LISI , LIS2 , ZIFF
und
COMMON-RANGE-TEST-TABLE so ausgewählt, daß das Verhalten der Funktionen deutlich wird. 9
Beginnen wir mit den no-spread-LAMBDA Funktionen. LIST-TEST erzeugt eine Liste, in der die Argumente top-level Elemente sind. In der Funktionsdefinition bedeutet L die Liste der beliebig vielen Argumente.
298
UN) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT) (OUT)
00 IRZP.LISP X P500 LOADING
(IN)
LOAD(UTILITIES)
(IN)
LOAD(BLOCKS-WORLD)
(IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT)
(SETQ XO NIL) NIL 5-
SIEMENS-INTERLISP
-
VERSION *t.O
•••••• RESET »•••••
(SETQ XI •(1)) (1) 6(SETO X2 ' (2 3)) (2 3) 7LIS2 ((ALPHA BETA) GAMMA 8-
(DELTA EPSILON))
LIS1 (ALPHA (BETA GAMMA) DELTA) 91SETQ LISO (LIST-TEST 'ALPHA 'BETA (ALPHA BETA GAMMA) 10-
'GAMMA))
(SETQ LIS3 (APPEND-TEST LISI XO LIS2Ì) (ALPHA (BETA GAMMA) DELTA (ALPHA BETA) GAMMA 11(NCONC-TEST LISO (LIST-TEST (ALPHA BETA GAMMA DELTA) 12LISO (ALPHA BETA GAMMA DELTA) 13(NCONC-TEST XO XI X2> (1 2 3) HX2 (2 3) 15XI (1 2 3) 16XO NIL 17-
'DELTA))
(DELTA EPSILON))
9.4
299
Ohne Angabe eines Arguments ist das Ergebnis NIL. Dies entspricht auch der Endbedingung und wird in Klausel 1 formuliert. Der Rekursionsschritt ergibt sich aus Betrachtung des einfachsten Falles: Wenn nur ein Argument angegeben ist, dann ist dieses der CAR von L und wird mittels CONS "in die (leere) Restliste" eingebunden. Das in Anführungszeichen stehende kann aber als rekursiver Funktionsaufruf bez. dem CDR von L aufgefaßt werden, wobei hier (wegen des no-spread Typs) APPLY für die korrekte Zuordnung der Argumente sorgen muß. 10 APPEND verknüpft die als Argumente angegebenen n Listen so, als ob (wie Siklfcssy /Si76/ es ausdrückt) die sich berührenden Klammer-Paare "verbrannt worden wären". Dabei kopiert APPEND die (n - 1) Argumentlisten, sodaß diese selbst nicht verändert werden (vgl. Merkblatt (l)). Die Test-Definition teilen wir zweckmäßig auf in die spreadLAMBDA Funktion APPEND2 zur Verknüpfung von zwei Listen und die APPEND2 aufrufende no-spread-LAMBDA Funktion APPEND-TEST . Beginnen wir mit APPEND2 : L1 und L2 sind die beiden zu verknüpfenden Listen. Der Trivial-Fall liegt vor, wenn L1 leer ist, dann ist L2 das Ergebnis. Statt des Tests mit NULL schreiben wir hier ATOM, denn dieser ist auch für die leere Liste gültig, ist aber "robust" gegen den Eingabe-Fehler, daß L1 ein beliebiges Atom ist . Der Rekursionsschritt ergibt sich aus dem einfachsten Fall, daß L1 nur ein Element hat, das dann als CAR von L1 mittels CONS (und somit als Kopie ! ) "in den Rest" eingebunden wird. Dieser besteht aus dem rekursiven Funktionsaufruf bez. CDR von L1. In APPEND-TEST bedeutet L die Argument-Liste. die ihrerseits aus den zu verknüpfenden Listen besteht. Ist L leer, so ist das Ergebnis NIL. Die Rekursion wird mit APPEND2 angesetzt : Die erste Liste (als CAR von L) soll
300
vor den "Rest" gebunden werden. Dieser besteht aus dem rekursiven Funktionsaufruf von APPEND-TEST bez. CDR von L (mit Hilfe von APPLY). Für spätere Verwendung speichern wir die Test-Resultate von LIST-TEST und APPEND-TEST mittels SETQ auf LISO bzw. LIS3. (Man beachte, daß sich die Argumentliste XO = NIL "beim Verbrennen" in Nichts auflöst.) 11 Im Gegensatz zu APPEND verknüpft NCONC die n Argumentlisten unmittelbar (vgl. Merkblatt (1)). Am Beispiel von LISO demonstriert dies NCONC-TEST. 13 Im folgenden Beispiel übergeben wir NCONC-TEST die Listen XO, X1, und X2. Das letzte Argument, X2,wird nicht verändert. An XI wurde X2 angehängt. Die leere Liste XO konnte aber von NCONC(-TEST) nicht verändert werden ! Ähnlich wie bei APPEND-TEST werden wir für NCONC-TEST zunächst die spread-LAMBDA Funktion NCONC2 zur Verknüpfung von zwei Listen definieren, die ihrerseits die rekursive Funktion 2NC0NC aufruft. 2NC0NC setzt voraus, daß der erste Parameter L1 eine nicht-leere Liste ist, sodaß in der 1. Klausel der CDR gebildet und als Endbedingung abgefragt werden kann. Ist das Ende von L1 erreicht, wird mit der destruktiven Systemfunktion RPLACD (vgl. Merkblatt (l)) L2 an L1 angehängt. Andernfalls wird 2NC0NC rekursiv auf den CDR von L1 angesetzt. NCONC2 prüft (robust) in der 1. Klausel, ob die Liste L1 leer ist: Dann ist das Ergebnis L2. Andernfalls wird 2NC0NC zum Verknüpfen von L1 und L2 aufgerufen. NCONC2 liefert als Ergebnis die modifizierte Liste L1. Die no-spread Funktion NCONC-TEST wird (wie bei APPENDTEST) mit NCONC2 angesetzt.
9.h
301 Die beiden folgenden Funktionen sind besondere Arten von Steueranweisungens Da der Fortschritt der Evaluierung von Bedingungen abhängig ist (Argumente evaluieren zu NIL bzw. nicht-NIL), müssen sie als no-spreadNLAMBDA Funktionen definiert werden.
17 OR-TEST ergibt (nach üblicher LISP-Konvention) ohne Argument NIL. Werden mehrere Argumente angegeben, wird der Reihenfolge nach evaluiert, bis ein Argument den Wert nicht-NIL ergibt. Dieser Wert ist Wert von OR-TEST. Evaluieren alle Argumente zu NIL, ist NIL der Wert von OR-TEST. In der Definition bedeutet L die Liste der beliebig vielen Argumente. Bei leerem L ist das Ergebnis NIL. Die nachfolgende Klausel besteht nur aus dem Prädikat: Evaluiert das erste Listenelement von L zu nicht-NIL, ist dieses das Ergebnis von OR-TEST. Andernfalls (letzte Klausel) wird rekursiv in der Restliste gesucht. 20 AND-TEST ohne Argument ergibt T (nach Konvention). Werden mehrere Argumente angegeben, so wird der Reihenfolge nach evaluiert, bis ein Argument NIL ergibt. Dann ist NIL Wert von AND-TEST. Evaluieren alle Argumente zu nicht-NIL, dann ist der Wert des letzten Arguments Wert von AND-TEST . In der Funktionsdefinition berücksichtigt die 1. Klausel die Konvention. Die 2. Klausel prüft, ob die Liste nur (noch) aus einem Element besteht. Dann ist dieses das Ergebnis von AND-TEST und liefert je nachdem NIL oder nicht-NIL. Ist die Restliste noch nicht leer, wird in der 3. Klausel geprüft, ob das erste Element von L zu nicht-NIL evaluiert. Wenn ja, wird rekursiv in der Restliste weiter gesucht. Wenn nicht, liefert die letzte Klausel das Ergebnis NIL.
302
(IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT» (OUT) (OUT) ( IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT)
(OR-TEST) NIL 18(OR-TEST NIL L I S 2 T) ((ALPHA BETA) GAMMA (DELTA 19-
EPSILON!)
(OR-TEST LISI L I S 2 NIL) (ALPHA (BETA G A M M A ) DELTA) 20(AND-TEST) T 21(AND-TEST LISI) (ALPHA (BETA GAMMA) 22-
DELTA)
(AND-TEST LISI NIL T) NIL 23(AND-TEST LISI L I S 2 T) T 24(LENGTH-TEST 0 25-
'GAMMA)
(LENGTH-TEST 3 26-
LISI)
(LENGTH-TEST
•(1 2 3 A . B))
27(SETQ L E I N S (COPY-TEST LISI)) (ALPHA (BETA GAMMA) DELTA) 28(EQUAL-TEST LISI NIL 29-
LIS2)
(EOUAL-TEST LISI T 30-
LEINS)
(EQ LISI NIL 31-
LEINS)
(SETQ LZWEI (APPEND-TEST L I S 2 ) ) ((ALPHA BETA) GAMMA (DELTA E P S I L O N ) ) 32(EQ L I S 2 NIL 33-
LZWEI)
9.4
303
2h LENGTH-TEST ist die erste der spread-LAMBDA Funktionen. Sie soll die Anzahl der top-level Elemente der Argumentliste L bestimmen. Anders als in der Version aus den "Übungen zur Einf. Übersicht" implementieren wir hier die robuste Endbedingung, die auch bei Eingabe eines Atoms ein definiertes Ergebnis liefert. Ist L leer (oder ein Atom), ist der Funktionswert 0 . Andernfalls wird LENGTH-TEST rekursiv auf die Restliste angesetzt, wobei der Wert jedes Aufrufs mittels ADD1 um 1 erhöht wird. 27 COPY-TEST soll eine Kopie der als Argument angegebenen Liste L erstellen.
Die 1. Klausel der Definition von
COPY-TEST erfüllt zwei Aufgaben s Wurde die Liste L bis auf Atome abgearbeitet (infolge rekursiver CARs), ist dieses Atom Wert der Endbedingung. Ist L die leere Liste NIL (infolge rekursiver CDRs), so ist NIL dieser Wert. Rufen wir COPY-TEST rekursiv sowohl für CAR als auch für CDR auf und verknüpfen die Teilergebnisse mittels CONS (das eine neue LISP-Zelle einrichtet ! ) , werden sämtliche Zweige der Struktur L durchlaufen und kopiert. Mit Hilfe von COPY-TEST kopieren wir LISI und speichern das Ergebnis mittels SETQ auf LEINS. Mit EQUAL-TEST (das wir gleich besprechen werden) können wir die Struktur-Gleichheit zeigen und mittels EQ beweisen, daß eine Kopie vorliegt, denn es wird keine PointerGleichheit festgestellt. Es sei angemerkt, daß APPEND, mit nur einem Argument aufgerufen, wie COPY wirkt, (vgl. Beispiel 31 , die Begründung in Abs. 9.1
und die Test-Definition.)
28 EQ testet auf Pointer-, EQUAL auf Struktur-Gleichheit. In EQUAL-TEST enthalten die ersten beiden Klauseln die Endbedingung : Wenn (1. Klausel) L1 ein Atom (oder die leere Liste) ist, dann ist das Ergebnis abhängig vom Test auf Gleichheit von L1 und L2 mittels EQ. Die 2.
9.4
304
Klausel wird erreicht, wenn L1 kein Atom ist. Wird nun festgestellt, daß L2 ein Atom ist, liegt Ungleichheit vor, das Ergebnis ist NIL. Sind L1 und L2 weder leere Listen noch Atome, wird in der 3. Klausel EQUAL-TEST als Prädikatfunktion rekursiv für die CARs von L1 und L2 benutzt. Wenn der Test nicht-NIL ergibt, dann wird rekursiv in den CDRs von LI und L2 weiter gesucht. Andernfalls (letzte Klausel) wurde Ungleichheit festgestellt; das Ergebnis ist NIL. 33 REVERSE-TEST erzeugt eine Liste, in der die Reihenfolge der top-level Elemente ihrer Argumentliste L umgekehrt ist. (Zur Umkehrung der Reihenfolge auf allen Ebenen vgl. REVERSALL in Aufg.(2l) .) Die Endbedingung lautet: Wenn L die leere Liste (oder ein Atom) ist, dann ist das Ergebnis NIL (bzw. dieses Atom). Die Reversierung verlangt: Nimm das erste Element und hänge es an den Schluß an, "usw." . Das erste Element ist der CAR von L . Anhängen macht APPEND. Damit APPEND "etwas zum Verbrennen hat", müssen dem Element mittels LIST noch zusätzliche Klammern gegeben werden. Im "usw." steckt der rekursive Aufruf bez. der Restliste. REVERSE-TEST erzeugt eine neue Liste; die OriginalListe bleibt unverändert, wie Beispiel 35 zeigt. 36 LAST liefert (in INTERLISP) den Zeiger zum letzten toplevel Knoten der Argumentliste. Ist es ein Punkt-Paar, so wird dieses zurückgegeben. LAST-TEST prüft zunächst (1. Klausel) den Fehlerfall, daß L ein Atom ist und liefert NIL. Die Endbedingung steckt in der 2. Klausel: Wenn die Restliste von L leer ist, enthält L nur noch ein Element (bzw.: Wenn der CDR ein Atom ist, so ist L ein Punkt-Paar); L ist das gewünschte Ergebnis. Andernfalls wird LAST-TEST rekursiv auf die Restliste angesetzt.
9.4
305
(IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) ( IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (INI (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT)
(REVERSE-TEST GAMMA 34-
•GAMMA)
(REVERSE-TEST LISI) (DELTA (BETA GAMMA) ALPHA) 35LIS1 (ALPHA 36-
(BETA GAMMA) OELTA)
(LAST-TEST NIL 37-
'GAMMA)
(LAST-TEST LISI) (DELTA) 38(LAST-TEST •(1 2 3 A . B)) (A . B) 39(MEMBER-TEST «GAMMA LISI) NIL 40(MEMBER-TEST «GAMMA LIS2) (GAMMA (DELTA EPSILON)) 41(MEMBER-TEST '(BETA GAMMA) LIS3) ((BETA GAMMA) DELTA (ALPHA BETA) GAMMA 42(NTH-TEST LISI 4) NIL 43(NTH-TEST LISI 2) ((BETA GAMMA) DELTA) 44(NTH-TEST LISI 1) (ALPHA (BETA GAMMA) DELTA) 45(NTH-TEST LISI 0) (NIL ALPHA (BETA GAMMA) DELTA) 46(NTH-TEST «GAMMA 1) GAMMA 47(NTH-TEST «GAMMA 2) NIL 48" (NTH-TEST «(A . B) 3) NIL 49(NTH-TEST « (A . B) 2) B 50-
(DELTA EPSILON))
306 39 MEMBER-TEST sucht das Argument LI in der Liste L2 des zweiten Arguments als top-level Element. Falls Übereinstimmung gefunden wird, dann ist das Ergebnis der Zeiger auf die Restliste mit L1 als erstem top-level Element. (Zur Suche auf allen Ebenen vgl. INSIDE in Abs. 6.1 .) Ist (1. Klausel) die zu durchsuchende Liste L2 leer, dann gibt es nichts (mehr) zu finden; das Ergebnis ist NIL. (Wir benutzen die robuste Endbedingung: Auch in einem Atom gibt es nichts zu suchen.) Die 2. Klausel enthält die Test-Bedingung: Wenn L1 gleich dem ersten Element von L2 ist, dann ist L2 das Ergebnis. Wenn nicht (letzte Klausel), dann wird rekursiv in der Restliste weiter gesucht. k2 NTH liefert den Zeiger auf den Rest der (als erstes Argument gegebenen) Liste L, die mit dem (als zweites Argument gegebenen) N - ten top-level Element beginnt. Ist N größer als die Anzahl der Elemente von L, so ist das Ergebnis NIL. Ist (erster Sonderfall) N = 0 , so wird (aus Konsistenzgründen) die Liste zurückgegeben, die NIL als erstes Element enthält. Aus den weiteren Reaktionen der Systemfunktion (vgl. Beispiele k6 bis k9) folgt die Definition: In der 1. Klausel von NTH-TEST wird der Fall N = 0 behandelt. Ist N = 1 (2. Klausel), wird L zurückgegeben; falls L ein Atom war, dann auch dieses. Ist dagegen N 71 , so wird (3. Klausel) L auf Atom (bzw. leere Liste) geprüft und liefert dann NIL. Falls L eine nicht-leere Liste ist, wird (letzte Klausel) NTH-TEST rekursiv für die Restliste aufgerufen und N reduziert. Diese rekursive Schleife wird solange abgearbeitet, bis die Endbedingung (normalerweise die 2. Klausel) erreicht ist.
9.h
307
50 REMOVE-TEST löscht auf top-level das erste Argument L1 in der Liste L2 des zweiten Arguments. (Zum Löschen auf allen Ebenen vgl. REMOVALL in Aufg.(22).) Ist die (robuste) Endbedingung nicht erfüllt, wird in der 2. Klausel geprüft, ob L1 gleich dem ersten Element von L2 ist. Wenn ja, so wird rekursiv in der Restliste weiter gesucht und damit ist das Element "gelöscht". Wenn nämlich nicht (letzte Klausel), dann muß das Element erhalten bleiben und wird mittels CONS in den "Rest" eingebunden. Dieser ist der rekursive Funktionsaufruf bez. Restliste. 51 Das Beispiel zeigt, daß durch die CONS-Operationen eine neue Liste erzeugt und nicht die Original-Liste verändert wurde. 53 SUBST-TEST arbeitet die gesamte Struktur der Liste L des dritten Arguments ab und ersetzt bei Übereinstimmung das zweite Argument OLD durch das erste Argument NEW. Ist L bis auf Atome abgearbeitet worden (infolge rekursiver CARs), dann wird in dem eingebetteten COND geprüft, ob OLD gleich L ist. Wenn ja, so wird NEW gesetzt, andernfalls bleibt L erhalten. Diese 1. Klausel des äußeren COND gilt auch als Endbedingung für die leere Liste ! In der 2. Klausel wird geprüft, ob OLD gleich dem CAR von L ist. Wenn ja, wird NEW mittels CONS in den "Rest", also den rekursiven Aufruf bez. CDR von L , eingebunden. Wenn nicht, wird in der letzten Klausel (wie bei COPY-TEST) die gesamte Struktur durchsucht und die Teilergebnisse werden mittels CONS verknüpft. 5b Wieder wird dabei die Original-Liste nicht verändert. 56 INTERSECTION-TEST bildet den Mengen-Durchschnitt der beiden Listen L1 und L2. Die Endbedingung wird wieder robust definiert. Die Test-Bedingung prüft, ob das erste Element von L1 MEMBER in L2 ist. Wenn ja, wird dieses Element in die "Ergebnisliste" mittels CONS
308
9.
(IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (IN) (OUT) (OUT) (OUT) (OUT)
(REMOVE-TEST 1 GAMMA LIS3) (ALPHA (BETA GAMMA) DELTA 51-
(ALPHA BETA)
LIS3 (ALPHA 52-
(ALPHA BETA) GAMMA
(BETA GAMMA) DELTA
(DELTA EPSILON))
(DELTA EPSILON))
(REMOVE-TEST •(BETA GAMMA) LIS3) (ALPHA DELTA (ALPHA BETA) GAMMA (DELTA EPSILON)) 53(SUBST-TEST «ZETA «(BETA GAMMA) LIS3) (ALPHA ZETA DELTA (ALPHA BETA) GAMMA (DELTA EPSILON)) 54LI S3 (ALPHA (BETA GAMMA) DELTA S5-
(ALPHA BETA) GAMMA
(SUBST-TEST 'ZETA «ALPHA LIS3) (ZETA (BETA GAMMA) DELTA (ZETA BETA) GAMMA 56-
(DELTA EPSILON))
(DELTA EPSILON))
(INTERSECTION-TEST LISI LISO) (ALPHA DELTA) 57(INTERSECTION-TEST LISI LIS2) NIL 58(UNION-TEST 'EPSILON LISO) (ALPHA BETA GAMMA DELTA) 59(UNION-TEST LISI LISO) ((BETA GAMMA) ALPHA BETA GAMMA DELTA) 60ZIFF ((NULL . ZERO) (EINS . ONE) (ZWEI . TWO) (DREI . THREE) (VIER • FOUR) (FUENF . FIVE) (SECHS • SIX) (SIEBEN . SEVEN) (ACHT . EIGHT) (NEUN . NINE)) 61(ASSOC-TEST »DREI ZIFF) (DREI . THREE) 62(ASSOC-TEST 'THREE ZIFF) NIL 63COMMON-RANGE-TEST-TABLE (((-1 -1 -1 -1)) ((1 1 1 1)) ((-1 -1 -1 0)) (I-I -I -I 1) • -I' ((-1 0 - 1 1 ) . -1) . • H C C i Cbtf » c » V. CM wiHPmasoE® M -H ® P h 0 CO.;*:-H«ppp®W S S ® B • H 05 I E C D « C -H £ Q 9I I . 3 3 U 3 C 3 W 3 :«l -r* h H O C W V > O C 9 (« N p Q C -( S w-a £ « J O n: £ «JZCEO W * tu e es C O O ® 3 Sö II I £ 0- -H « W-H O 3 < X P ® • 9 I. U Wh EWU £ -H c W 9 9 c < s ® a S c 3M X O 3 • -H • -H -P 9 O S C -P £ - -J ^ < -H - " 0 3 K J d £ « > e' • 3 * X X O » (h £ { ® C 3 < K ob.«) £ W* • "D 9 •n C 3 W C -> £ -H l • 3 C 1 / 5 U ü Q Q, • •0 X • U W 9 trt :3 -H J 3 U * U U v< E « ® h £ --H«IE WlnHt.« Ä-D* Q O W h V C -H ® ® -h H © H i m ® a-H v> 3 x w o b « < a V)fl0 tu) W-J ( 9 2 9 « 4 0. • :o 4 -H h J -H W 9 < H • c m ^ «WhhU 1 £ VI «-H x +> E -P * h t 3 e x •n e ki h u « P «I « O P B 9 V -rl• X B « < m u -o « « H i C B TJH NÄ 9 3 ö B i32 i. Ob ® ® U In H 0 C £ O § ki 0 h h £ 9 O U 0 M*9 1 -H W kl 3 « J Ä P ® X 9 £ . 1 « c < a u ¡3 t tl -J — 3 -H £ 9 ® -H •p £ O ft. X £ • W 9 C • Ji n 3 3fa.* H C 3 h « £ Ä 3 < ® © -o p ® < m ® £ £ - M ® N kl 1 h wh > d h c U X W c • • 0 O^hA 3 3 • U« O O 9 C 3 < 0 -H 0 TJ ffl E-H3(41« - 9 U N HE Ji £ Q 3 -H -0 £ OCCH£«j~mPd to T* a P • (D 3 C A 3 W O N Tl 3 E — -H •• 9 —' u < m ® o C C P HN -H « h U J d o W -H 9 £ £9 n -H 9 0 Ü I CS« -HRTin - I i 9 "DO C*H«n-H C 9 > O Oa i B £ < H < M Q m |U ® O -p C n -h £ H W W -w e • H H 9 « n B d u E U m • P H £ 0 l< X 9 H 9 H < M N O C P O C :o C C 9 W-H O H £ C B>OC(H«9E3« -PO U £ V O PP T5 £ - * -H h 9 Ü •P ® H 9 t jrtu T3 W l« to k a o c 3 » 1 0 3 0 O ®£ o a h ® p > tj a e Wh u 9 O K -H « £ e N O « < H ffl I K * WWXB -HBOO-O • < M 6 £ -a w 0. -rt X ® • W ,ß ® H 9BB0-PBA3E C B S C I « C C OfciO P £ • H i w W£ a E a * £ h d d -h a e Q B U X 9 ' BOB" C d N E > p 9 3 ^< 9 3 9 < Q ® 1 C O £ (8 ® U B 9 W B U h « a OB h h " TJ ® ti * ® U 9 C < " -CC 9 ® £ C ^ o 0 kl < £ H J 0 HCCSCh iH £ W ® ti C O «h.0 E > ® ® * (B -H 0) ® -H M I C E "H tf• 9 d 0 9 h n O 9 C -P ® £ ®fflfl> W D ® P93C W «-I X ® E C U 9 B HJIC KU TJ X B B f) pi 9 9 © 9 « C C 9 U « -HO ® Ifl Tl -H ® 8 O C IQ « • H < m ® 3 ® -H C B W 3 -p + > C « P ® k.ftp ® -h : u £ £ ® 9 a -M H x £ ® B ® 0 O B < 3 C 9 0 £ C Jio ^ « W £ 9 p 2 o a B -rt -H WO « C -H £ ® C -H H i H < :0 c •H»3CCO«:a3« £ P • p B•rl P o E « H p 9 £ c 3 s a ® X oh«® 9 (0 3 3 TlH ® a N TJ « JCd HO'k£C®J!P X B k < h £ E £ X X 4 X U WC W P a) -H i Sp EU «U-H'DOO 3 0 3 U -H 9 • H U O P • « ^ K ) > II t O Q Z * «« > V 1 * w * > 9 9 3 0 9 < £ H w ® ® O. 0 -UH JriH* 2 In U » • £ I 3 0.0 -PS E h O ft, na;® W,~- ® f) c/i D p 'flh p n i 9 U l a >i C * E ® m Jd E ® h k > 0 X C O • H H®< 0 «—»H ®«
3 l N e P 3 •3
«
I
f
^
-hft3 t o 3 a 3 ® O E • a ki o 3 v> o o J
W 9 > >fc.C ^ J ® 3 H D i W£
I B » I p ® C kl ffl I C 9 9 p I 0 W N C
3 Tl 5 9 h B W k 9 C £ T. k, ®fflki d h -P 4 O ®ffl> -H9 k. « > £ U 9 P -rt 0 3 ki £ N 9 9 K WH • ® h £ • C £ 3 • W 0 ki 9 9 PEfc.CE 0 H 9 M U 9 W £ © C C E +
E ® H ft E H
d U £ -p « 3 W o Ji X : sei/) er k. • 9 e .> "0 S 3 •i C £ V. ® n H » 9 T3 t 9 O "0 P 9 PC») 9 •l £ W C U £ 9 9 h U £ 2 -H* iH 9 3 » 9 ü O • « » ki O ü ^ a -0 c w • • 3 C O B (•
•PESO C kl £ -H » ® V U H )C 5 «1 ® P HM TJ B 3 B U C • 5 ® £ ® "0 0 H ® £ a t. J N £ J £ W 1 O O I) 9 -Hb 9 £ I H aP tiCJ 5 E 3 » 9 W
323 M
E
R
K
B
L
•> • « -«j x < X H U. £ l. i o.
A
T
e s ® a E TJ E C 0 4
0 h o. 9 C -H
( 2 )
zum
A n h a n g
•
N *) N ® k h • a Q. V E *
® 3 £ U » E h O C 3 0 jH a n V L. id c c e u o « c < > E ® O 3 W = fc c • a .
A - 1
•ot.
I. E G * 0 3 » *l « J • o ' 0. £ s 0 * 0 , ® . * *> t< ®
T
X t- H W £ O d 00 «
TJ ffl C H C l 9 s E
> I H c tj h ® ® kk— 3 H E X C 3
+> O ® X
t:u3 U
¿ S < « 3 0 U
c
> • a
® O M N " -w C O H 3 C TJ £ X Ii U. 3 !K «1 1 I l« 10 3 < 3 fill) I N . B i £ i t ^ o « : « -h K -J h H 9 1 Z « N 13 tT B c • 9 h 9 C ) U £ C £ i o. ® h o
• * u •p CO C O H tf h x a cd O 3 t-
W « « fd ED! £ « J Gl 03 C O 0. 3 H I • H U E - P • h H H M ® £ £ C •ü »1 E 3 H C ® « u. -H » e •w «< 0 ® X £ H C * « « 3 £ Cfa.hU O 0 ® H • £ H •> « W £ C • :3 ® « C 3
H 9 n i * 3 i< i c 9 o H -wo® u H m a
9 c a C 9 I « £ C U I • W O H 13 s E H H 9^ * ® +J N I O c H i W « U 0 » C 3 H C H V 3 6 c H •*> «1 U. J H » H M-W ® 0 Z t> C N 3 *> ® n C U M » • C «0 G. N W H B »1 C h H 1 £ *» C • * C h « « V TJ 9 E *> X X o X « ® £ 3 i H H U 9 • 3 C 9 ® b fe b h H « • (6 • w e i l . • c ® 0 N « C O V H £ 9 H C fl « « » « H U H 3 C h • a«H 3 • 9 > U U TJ > V ® ® H N £ > ® e n g EH • n h • C o h ® 9 6000 o . a . h 00 • » M J : Ä ® H 9 « C H . J i « 3 S H •>
N ® • • E « •) C ** 3 « 9 £ « W & V C »1 H ti H VO 3 h Ü ® H 00 H 9 s > MOT3 *> :o 00 e * C E ffl 3 N l< H x e c 1 »b. 9 3 (9 E « *> > h o ® • H • WD k 3 Q n CT) h O ® « t< ® O C OB V U OO h *> 9 b < O C • H -P 9 r 1 o u "o ® v a > a w ^ H * £ I H 9 - — « N E ® u. X : X> +> C ¿> 9 O « 3 H h 9 £ "O 60 C £ 4 H * 3 •> 0 U (9 O • 3 « 9 C H •) < J i TJ £ C :fl h •H b S C £ U £ I E C H * «> E H HO 9 ® •D H C C 60 E H e +» 9 c c ® a H X e H H -W « 9 C C > ® » H 3 ro 9 • * u, x w« co m
is§
C « « 3 h Vi h £ 3 ® O fl £
9 H 3 H >
" i S
*> H x J • 3 fi.EE n
T5 3 C
I Z
O V) £ m i g a e H » ® o 0 a
5 ® U •( (9 H
3 1 n < hl
H £ S
S r- OCO •) r-. O. J - ü) y
INTERSECTION
Erzeugt Mengen-Durchschnitt bez. top-level Elemente beider Listen LAMBDA
par, body
21
Definition eines funktionalen Ausdrucks LAST
list
17
Restliste mit letztem top-level Element der Liste LENGTH
list
kl
Ermittelt Anzahl der top-level Elemente der Liste LESSP
xf y Test auf
56
x