home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
language
/
prolog68.zoo
/
doc
/
liesmich
next >
Wrap
Text File
|
1992-02-23
|
21KB
|
643 lines
-------------------------------------------------------------------------------
/¯¯¯¯¯) /¯) /¯¯¯¯¯) /¯¯¯¯¯)
/ /¯) / / / / ____/ / /¯) /
/ (_/ / / / / / / (_/ /
/ ____/ /¯¯¯¯) /¯¯¯¯¯) / / /¯¯¯¯¯) /¯¯¯¯¯) /¯¯¯) / ¯¯¯) / /
/ / / /¯¯¯ / /¯) / / / / /¯) / / /¯) / (___/ / /¯) / / /¯) /
/ / / / / (_/ / / / / (_/ / / (_/ / / (_/ / / (_/ /
(_/ (_/ (_____/ (_/ (_____/ (___ / (_____/ (_____/
/ /
/¯¯¯¯ /
(_____/
(Vorab-Version)
© Copyright 1989,1990,1991,1992 Jens Kilian
Alle Rechte vorbehalten
------- Inhaltsverzeichnis ----------------------------------------------------
DEMO Demonstrationsprogramme
QUEENS.PL
RANDOM.PL
WORM.PL
CODES Vorübersetzte Versionen von Compiler und
BUILTINS.WAM Laufzeitsystem
DEBUGGER.WAM
DRIVER.WAM
DSTRUCT.WAM
ENCODER.WAM
INDEXER.WAM
LIBRARY.WAM
SHELL.WAM
TMPALLOC.WAM
XLATOR.WAM
DOC
LIESMICH Dieses Dokument (deutsche Version)
README Dieses Dokument (englische Version)
PROLOG68.DVI Vorläufige Dokumentation
INIT.WAM Initialisierungsdateien
PROLOG.LST
WAM.TOS Hauptprogramm (Emulator, Systemfunktionen)
------- Kurzbeschreibung ------------------------------------------------------
Diese Diskette enthält die Vorabversion 0.9.126 von Prolog-68, einem neuen
Prolog-System für den ATARI ST. Wenn das Programm fertiggestellt ist, wird es
als freie Software (NICHT als Public-Domain-Software !) zusammen mit dem
Quellcode öffentlich zugänglich sein.
Die vorliegende Version darf frei verbreitet, aber NICHT verändert oder
kommerziell genutzt werden. Als kommerzielle Nutzung gilt auch der Vertrieb
über einen Public-Domain-Versand, sofern die erhobene Gebühr für den Versand
einer Einzeldiskette die Summe aus Diskettenpreis und Versandkosten um mehr
als DM 2,- übersteigt.
Noch einmal: Dies ist eine Vorabversion, d.h. daß ich noch nicht einmal
dafür garantiere, daß die hier gemachten Aussagen zutreffen !
Prolog-68 basiert auf der `Warren Abstract Machine'; es enthält einen (in
Prolog geschriebenen) Compiler, der die Programmklauseln in einen Zwischencode
übersetzt. Der Zwischencode wird als `direct threaded code' gespeichert und von
einem Simulator abgearbeitet. Das Systemm erreicht so eine Geschwindigkeit
von 12 kLIPS unter dem 'nrev'-Benchmark, was für Prolog auf dem Atari ST einen
durchaus annehmbaren Wert darstellt. Das Programm wurde auf einem Atari ST mit
4MB Hauptspeicher getestet, sollte aber auf allen ST-Modellen mit
68000-Prozessor (!) lauffähig sein. Wie üblich gilt für den verfügbaren
Speicher `mehr ist besser'; benötigt werden mindestens 250 KByte, um das
Programm überhaupt laden zu können. Die Dateien im Ordner 'CODES' enthalten
eine bereits übersetzte Version des Compilers und der Benutzerschnittstelle.
DIESE DATEIEN DÜRFEN AUF KEINEN FALL VERÄNDERT WERDEN !
Da weder Compiler noch Laufzeitsystem fertig sind, muß der Benutzer momentan
auf Datenbankfunktionen ('assert', 'retract') und einige andere Features
verzichten. Außerdem sind die Namen der Prädikate des Compilers offen sichtbar
(jedenfalls für ein Programm), so daß man den Compiler durch Benutzung
von 'consult' wunderbar zerschießen kann.
------- Bekannte Fehler -------------------------------------------------------
Die vorliegende Version 0.9.126 hat folgende Fehler, die in zukünftigen
Versionen behoben sein werden:
* erase/1 gibt den Speicher für gelöschte Terme nicht wieder frei
------- Vordefinierte Prädikate -----------------------------------------------
Ich bemühe mich, ein möglichst vollständiges Prolog zu erstellen, das zu den
Standard-Dialekten wie Prolog-10 und Quintus Prolog weitgehend kompatibel ist.
Die meisten vordefinierten Prädikate sind bereits implementiert, können aber
hier nur kurz beschrieben werden:
- Steuerung:
','/2
';'/2
'!'/2 (s.u.)
'->'/2 (s.u.)
call/1
'\+'/1 (wie not/1 in TOY Prolog)
true/0
otherwise/0 (= true/0)
fail/0
false/0 (= fail/0)
repeat/0
if_exception/3 (Fehlerbehandlung, s.u.)
signal_exception/1
signal_error/3
propagate_error/4
trap/2
set_error_handler/3
once/1 (wie in TOY Prolog)
if_exception/3 und signal_exception/1 wirken ähnlich wie tag/1 und
tagexit/1 in TOY Prolog. Mit
if_exception(?ErrorTerm, +Goal, +Recovery)
kann man 'Goal' aufrufen. Wird während der Abarbeitung von 'Goal'
signal_exception(?Term)
aufgerufen, dann wird 'Term' mit 'ErrorTerm' unifiziert und danach
'Recovery' aufgerufen und der ursprüngliche Aufruf von if_exception/3
verlassen. Alle in 'Goal' vorgenommenen Variablenbindungen werden dabei
(wie bei einem Fehlschlag) rückgängig gemacht.
Die Prädikate
signal_error(+Type, +Arg, +Goal)
propagate_error(+Type, +Arg, +Goal, +Context)
trap(+Goal, +Handler)
set_error_handler(+Type, -OldHandler, +NewHandler)
dienen zur Fehlerbehandlung. Die Details können sich noch ändern,
deshalb sollten diese Prädikate momentan noch nicht benutzt werden.
Der 'cut' funktioniert auch innerhalb von Metacalls, er ist dort
aber in seiner Reichweite beschränkt. Im Aufruf 'call(X)' wirkt ein
in 'X' vorkommender 'cut' nur innerhalb der Klammern. Eine Faustregel:
`Buchstaben blockieren den cut'.
'->'/2 wirkt wie ein 'cut', der auf einen Teil einer Klausel
beschränkt ist. Der Aufruf (P -> Q; R) wirkt wie ein IF/THEN/ELSE-
Konstrukt: kann P erfüllt werden, dann wird Q aufgerufen, andern-
falls R. (P -> Q) allein wirkt wie (P -> Q; fail).
- Ein-/Ausgabe:
Dieser Teil des Programms ist fast vollständig. Kennt jemand ein
Prolog-System auf dem ST, das noch mehr bietet ?
read/1 Ein-/Ausgabe von Termen
write/1
writeq/1
display/1 (Ausgabe immer nach 'user' !)
write_canonical/1 (Ausgabe in Präfixform, heißt auch displayq/1)
print/1 (Ausgabe über portray/1, falls vom Benutzer
definiert)
portray_clause/1 (Ausgabe von Klauseln in leicht lesbarer Form)
get0/1 Ein-/Ausgabe von Zeichen (als ASCII-Werte)
get/1
skip/1 *
put/1 *
nl/0
tab/1 * diese Prädikate können einen arithmetischen
Ausdruck als Parameter erhalten.
is_endfile/1 Dateiendezeichen festlegen
is_newline/1 Zeilenendezeichen festlegen
is_newpage/1 Seitenendezeichen festlegen
is_endline/1 Zeilenende erkennen (nur mit instantiiertem
Argument aufrufen !)
open/3 Verwaltung von Datenströmen (s.u.)
open_null_stream/1
close/1
current_stream/3
nofileerrors/0
fileerrors/0
flush_output/1
set_input/1
set_output/1
current_input/1
current_output/1
absolute_file_name/2
read/2 Ein-/Ausgabe von Termen auf beliebige Datenströme
write/2
writeq/2
display/2
write_canonical/2 (heißt auch displayq/2)
print/2
get0/2 Ein-/Ausgabe von Zeichen auf beliebige Datenströme
get/2
skip/2 *
put/2 *
nl/1
tab/2 * (siehe oben)
character_count/2 Abfrage von Datenströmen
line_count/2
line_position/2
stream_position/3 Schreib-/Leseposition abfragen und setzen
stream_position/2 Positionen aller offenen Dateien abfragen
see/1 Prolog-10-kompatible Dateiverwaltung
seeing/1
seen/0
tell/1
telling/1
told/0
ttyget0/1 Prolog-10-kompatible Ein-/Ausgabe von Zeichen auf
ttyget/1 den Datenstrom 'user'
ttyskip/1
ttyput/1
ttynl/0
ttytab/1
biosget0/1 (nur für Demoprogramme)
biosput/1
biosstat/0
op/3 (Operatoren definieren & löschen)
current_op/3 (Operatoren abfragen)
sread/2 (Term mit Symboltabelle lesen)
sread/3 (dasselbe mit Angabe eines Datenstroms)
Die Prädikate zur Arbeit mit Datenströmen stammen aus Quintus Prolog.
Ein Datenstrom ist ein spezielles Objekt, das z.B. mit
open(+Dateiname, +Modus, -Datenstrom)
erzeugt werden kann. `Dateiname' ist der Name einer Datei, `Modus' muß
eines der Atome 'read', 'write', 'append', 'read_binary',
'write_binary' oder 'append_binary' sein. Der erzeugte Datenstrom kann
in Prädikaten wie z.B.
write(+Datenstrom, ?Term)
benutzt und mit
close(+Datenstrom)
wieder geschlossen werden.
Neben diesen Datenströmen für Dateien gibt es noch vordefinierte
Datenströme, die über folgende Namen angesprochen werden:
user (kompatibel zu Quintus Prolog)
user_input
user_output
user_error
printer_output (Erweiterung für den Zugriff auf ST-Schnittstellen)
modem_input
modem_output
midi_input
midi_output
ikbd_output
Mit write(printer_output, T) wird beispielsweise der Term T auf
den Druckerport ausgegeben.
Die 'read'-Prädikate sind in der vorliegenden Version vollständig
kompatibel zur Edinburgh-Syntax (wie sie z.B. in C-Prolog oder Quintus
Prolog benutzt wird).
- Arithmetik
'is'/2 Auswertung von Ausdrücken
'=:='/2 Vergleich von Ausdrücken
'=\='/2
'<'/2
'=<'/2
'>'/2
'>='/2
- Termklassifizierung:
var/1 (wie üblich)
nonvar/1
atom/1
integer/1
atomic/1
nonatomic/1 (Verneinung von atomic/1)
constant/1 (NICHT dasselbe wie atomic/1)
nonconstant/1
composite/1 (prüft, ob Term zusammengesetzt)
simple/1 (Verneinung von composite/1)
callable/1 Aufrufbarer Term (nonvarint/1 in TOY Prolog)
- Strukturzugriff:
functor/3
arg/3
'=..'/2
name/2 Konvertierung zwischen Konstanten und Strings
atom_chars/2
number_chars/2
numbervars/3 Variablen numerieren (z.B. für write/1)
- Vergleiche von beliebigen Termen:
'=='/2
'\=='/2
'@<'/2
'@=<'/2
'@>'/2
'@>='/2
compare/3
sort/2
msort/2
keysort/2
Beim Vergleichen von Termen mit '@<', ..., '@>=' wird folgende
totale Ordnung über der Menge aller Terme benutzt:
a) Variablen @< Zahlen @< Atome @< Zusammengesetzte Terme
b) Variable1 @< Variable2 ist eindeutig definiert, hat aber
keine Aussagekraft für den Benutzer
(... in der Edinburgh-Bibliothek wird
dieses Feature für einige Tricks benutzt,
für die `schmutzig' noch eine zu milde
Bezeichnung ist)
c) Zahl1 @< Zahl2 wenn Zahl1 < Zahl2
d) Atom1 @< Atom2 wenn der Name von Atom1 lexikographisch
kleiner ist als der Name von Atom2 (wie in TOY
Prolog)
e) Term1 @< Term2 wenn i) die Stelligkeit von Term1 kleiner als
die Stelligkeit von Term2 ist
ii) die Stelligkeiten gleich sind und
Funktor(Term1) @< Funktor(Term2)
iii) die Stelligkeiten und Funktoren gleich
sind und es ein i gibt, so daß
für alle j, 1 ≤ j < i:
Argument(Term1, j) == Argument(Term2, j)
und
Argument(Term1, i) @< Argument(Term2, i)
compare/3 verhält sich so, als ob es wie folgt definiert wäre:
compare('<', X, Y) :- X @< Y.
compare('=', X, Y) :- X == Y.
compare('>', X, Y) :- X @> Y.
sort/2, msort/2 und keysort/2 sortieren Listen gemäß der obigen
Ordnungsrelation. sort/2 entfernt doppelt vorkommende Elemente,
msort/2 tut dies nicht; keysort/2 erwartet eine Liste, deren Elemente
die Form
Key - Value
besitzen. Dabei werden die 'Values' ignoriert, die 'Keys' dienen als
Sortierschlüssel. keysort/2 behält doppelt auftretende Elemente bei;
diese erscheinen im Ergebnis in derselben Reihenfolge wie im Original.
Beispiel:
| ?- keysort([4-a, 1-b, 5-c, 1-d, 4-e, 0-f], Sorted).
Sorted = [0-f, 1-b, 1-d, 4-a, 4-e, 5-c]
Diese drei Prädikate haben im besten Fall linearen Aufwand, im
schlechtesten Fall sind sie O(NlogN) (woraus messerscharf geschlossen
werden kann, daß es sich hierbei NICHT um 'Quicksort' handelt).
- Programmzustand:
listing/0 Alle Prädikate auflisten
listing/1 Einige Prädikate auflisten
current_atom/1 (Abfrage von momentan bekannten Atomen etc.)
current_predicate/2
halt/0 (Programm anhalten)
halt/1 (dito, mit Angabe des Exit-Codes)
break (Verschachtelte Instanz von Prolog aufrufen)
abort (Programmabbruch und zurück zum ersten Prompt)
- Debugger:
Jaha, es gibt endlich einen, auch wenn er ein bißchen anders
funktioniert als allgemein üblich (seufz).
trace/1 (Debugger starten)
debug/1
nodebug/0 (s.u.)
trace/0
debug/0
spy/1 (Haltepunkte setzen & löschen)
nospy/1
nospyall/0
leash/1 (Gibt an, wo der Debugger anhält)
harness/1 (wie leash/1, für Spypoints)
debugging/1
unknown/2 (Überwachung undefinierter Prädikate)
Der Debugger wird mit trace(+Goal) im Einzelschrittmodus (creep),
mit debug(+Goal) im Ablaufmodus (leap) gestartet und auf den Aufruf
'Goal' angesetzt. trace/0, debug/0 und nodebug/0 funktionieren nur,
wenn der Debugger bereits aktiv ist. Bei Fehlern wird NICHT automatisch
der Debugger aktiviert.
unknown(-OldAction, +NewAction) ist eine abgekürzte Version von
prolog_flag(unknown, -OldAction, +NewAction) (siehe dort).
Nähere Informationen kann ich hier nicht geben, sie sollten aber
in jedem besseren Prolog-Lehrbuch stehen.
- Datenbank:
Es gibt im Moment keine Datenbankfunktionen ! (siehe aber unten)
- Datenbankverweise:
Datenbankverweise dienen zum schnellen Zugriff auf gespeicherte
Klauseln, Terme etc. Es gibt zwar noch keine Datenbankfunktionen
für Klauseln, aber die interne Datenbank ist vollständig implementiert.
Deshalb gibt es das Prädikat
erase/1 (lösche einen Datenbankverweis)
- Interne Datenbank:
Die interne Datenbank gibt es nur aus Effizienzgründen. Mit den
zugehörigen Prädikaten können nur Terme, keine Klauseln gespeichert
werden.
Auch dieser Teil des Programms ist so gut wie komplett.
recorda/3 (s.u.)
recordz/3 (s.u.)
recorded/3 (s.u.)
current_key/2
Mit recorda(+Schlüssel, +Term, -Verweis)
bzw. recordz(+Schlüssel, +Term, -Verweis)
kann der `Term' unter dem `Schlüssel' in der internen Datenbank
gespeichert werden. Als Ergebnis erhält man einen `Verweis' auf
den gespeicherten Term, der zum Löschen über erase/1 verwendet
werden kann. Mit recorded(+S, ?T, ?V) kann man den gespeicherten
Term wieder zurückholen. current_key(?KeyName, ?KeyTerm) ermöglicht
die Abfrage aller vorhandenen Schlüssel.
- Mengenoperationen:
setof/3 und bagof/3 sind noch nicht implementiert. Es gibt eine
abgemagerte Version von bagof/3, die identisch mit dem bagof/3
von TOY Prolog ist (aber nicht dem Standard entspricht).
findall/3 Ersatz für bagof/3
Der Unterschied zwischen dem Standard-bagof und dem von TOY Prolog
liegt in der Behandlung freier Variablen in dem Aufruf, der als zweiter
Parameter übergeben wird. Das Standard-bagof sammelt alle Lösungen,
für die sich für diese Variablen der gleiche Wert ergibt, während
findall/3 (und bagof/3 in TOY Prolog) alle diese Variablen als
existenzquantifiziert ansieht.
- Grammatikregeln:
expand_term/2 Wird aufgerufen, bevor eine eingelesene Klausel
kompiliert wird; erledigt die Umsetzung von
Grammatikregeln. Der Benutzer kann das Prädikat
term_expansion/2 definieren, um zusätzliche
Umsetzungen vorzunehmen.
phrase/3 Aufruf einer Grammatikregel
phrase/2
Bei phrase/[2,3] darf statt eines einzelnen nicht-terminalen Symbols
(wie in TOY Prolog) eine ganze Phrase (rechte Seite einer Grammatik-
regel) angegeben werden. phrase/2 ist folgendermaßen definiert:
phrase(Phrase, Liste) :- phrase(Phrase, Liste, []).
- sonstiges:
'='/2 (Unifikation)
length/2 (Länge einer Liste)
member/2 (Element einer Liste)
memberchk/2 (dito, aber deterministisch)
append/3 (Listenverkettung)
- spezielle Prädikate (Kompatibilität mit Quintus Prolog)
prolog_flag/3 (Globale Flags setzen)
prolog_flag/2 (Flags abfragen)
prompt/2 (Eingabeprompt abfragen bzw. setzen)
statistics/0 (Statistiken ausgeben)
statistics/2 (Statistiken abfragen)
prolog_flag/2 und prolog_flag/3 verwalten globale Flags, die
bestimmte interne Abläufe steuern. Der Wert eines Flags ist - im
Gegensatz zu anderen Prolog-Systemen - immer eine Integerzahl.
Im Moment gibt es folgende Flags:
Name Werte (Default) Funktion
character_escapes 0, 1 (0) Auswertung von Escape-Sequenzen
bei der Ein- und Ausgabe.
fileerrors 0, 1 (1) Ausgabe von Fehlermeldungen bei
nichtexistierenden Dateien etc.
gc_trace 0, 1, 2 (0) Ausgabe von Informationen über
Speicherbereinigung (0=keine,
1=Kurzmeldung, 2=vollständig)
unknown 0, 1 (1) Behandlung undefinierter
Prädikate (0=Fehlschlag,
1=Fehler erzeugen)
error_handling 0, 1, 2 (2) Art der Fehlerbehandlung
(0=nur Fehlschlag, 1=Aufruf
einer Fehlerbehandlung,
2=zusätzliche Fehlermeldungen)
Mit prolog_flag(+Flag, -OldValue, +NewValue) kann man den Wert eines
Flags verändern. prolog_flag(?Flag, ?Value) dient zur Abfrage ohne
Veränderung.
statistics/2 erhält als ersten Parameter eines der folgenden
Schlüsselworte:
'runtime' Laufzeit wird erfragt
'memory' Abfrage der verschiedenen Speicherbereiche
'core' (mehrfach belegt, z.B. heap = program)
'program'
'heap'
'global_stack'
'local_stack'
'trail'
'garbage_collection' Statistiken über Speicherbereinigung
Der zweite Parameter wird mit einer Liste von Zahlen unifiziert, die
das Ergebnis der Abfrage darstellen.
- systemabhängige Prädikate:
garbage_collect/0 Erzwingt eine Speicherbereinigung.
Wird normalerweise nicht benötigt, ist nur aus
Kompatibilitätsgründen vorhanden.
system/1 Übergabe eines Atoms an eine Shell (funktioniert
z.B. mit Guläm)
In einer der nächsten Programmversionen wird sich der Name dieses
Prädikats aus Kompatibilitätsgründen ändern ...
Es ist mir klar, daß die oben gemachten Beschreibungen bei weitem nicht
ausreichen. Leider habe ich noch keine vernünftige Dokumentation, die ich
mitliefern könnte; ein mit LaTeX geschriebenes Handbuch ist aber zumindest
in Arbeit (wer TeX noch nicht hat, sollte sich zumindest nach einer
Ausgabemöglichkeit für DVI-Dateien umsehen, z.B. an der nächsten Uni). Eine
vorläufige Version liegt bei.
------- Demonstrationsprogramme -----------------------------------------------
Der Ordner 'DEMO' enthält zwei Beispielprogramme: eine Version des bekannten
n-Damen-Problems ('QUEENS.PL') und ein kleines Spiel ('WORM.PL', 'RANDOM.PL').
Aufruf:
| ?- ['demo\queens'].
| ?- queens(N). für das N-Damen-Problem (N >= 4)
oder | ?- test. für das 5-Damen-Problem
| ?- ['demo\worm', 'demo\random'].
| ?- worm. (Steuerung über die Tasten 2, 4, 6, 8 auf dem
Ziffernblock)
------- Sonstiges -------------------------------------------------------------
... Meine Adresse hat sich geändert:
Jens Kilian
Holunderstraße 19
D-W-7033 Herrenberg-Gültstein
... e-mail an:
Internet: jensk@hpbbrn.bbn.hp.com
MausNet: Jens Kilian @ BB
... Ich sehe mich zu folgenden Äußerungen gezwungen, weil es zu viele
unvernünftige Menschen gibt:
Ausschluss der Gewährleistung
- Weil das Programm kostenlos genutzt werden darf, wird für das
Programm keinerlei Gewährleistung eingeräumt, soweit dies gesetzlich
zulässig ist. Falls nicht anderweitig schriftlich angegeben, stellen
die Urheber und/oder Dritte das Programm `so wie es ist' zur
Verfügung, ohne Gewährleistung jedweder Art, eingeschlossen die Gewähr
zur Erreichung eines bestimmten Verwendungszwecks, aber nicht
beschränkt auf diese. Die Benutzung erfolgt auf eigene Gefahr; das
gesamte Risiko in Bezug auf Qualität und Leistung des Programms liegt
bei Ihnen. Sollte sich das Programm als fehlerhaft erweisen, so tragen
Sie alle Kosten für anfallende Wartungs-, Reparatur-oder
Korrekturarbeiten.
- Soweit gesetzlich zulässig, haften die Urheber oder Dritte, die das
Programm wie oben gestattet verändern und/oder weiterverbreiten, für
keinerlei Schäden (einschliesslich irgenwelcher unmittelbaren Schäden,
mittelbaren Schäden, Folgeschäden und Drittschäden), die aus der
Benutzung oder der Unmöglichkeit der Benutzung des Programms entstehen
(einschliesslich des Verlusts oder der Verfälschung von Daten,
irgendwelcher materiellen Verluste, die Ihnen oder Dritten entstehen,
oder des Versagens des Programms, mit irgendeinem anderen Programm
zusammenzuarbeiten, aber nicht beschränkt auf diese), sogar in dem
Fall, daß besagten Urhebern oder Dritten die Möglichkeit der
Entstehung solcher Schäden bekannt war oder bekannt gemacht wurde.
-------------------------------------------------------------------------------
Viel Spaß,
Jens Kilian