Die Wortstrukturabstraktion

Rudolf Weber 1994

Überblick

Es wird die Struktur von Worten einer Sprache als Abstraktion identifiziert. Dann werden theoretische und praktische Anwendungen vorgestellt.

Theoretische Fundierung

Grammatiken, Wortvariablen und Substitutionen

Die syntaktischen Komponenten einer Formel in der Mathematik oder Physik sind Konstanten, (arithmetische,Differential-,...) Operatoren, Funktionssymbole, und Variablen (sowohl für Konstanten als auch für Funktionssymbole).
Die zulässigen Formeln sind Wörter einer Sprache, z.B. der mathematischen Formelsprache. Solche Sprachen lassen sich meist durch eine kontextfreie Chomsky-Grammatik beschreiben:

kontextfreie Chomsky-Grammatik

Eine kontextfreie Chomsky-Grammatik ist ein Tupel G = (T,N,P,S) mit

T : Menge1 der terminalen Symbole
- dies sind die Symbole/Zeichen, die dann am Ende stehen bleiben
T* ist die Menge aller Wörter, die man aus aneinanderreihen von Symbolelementen aus T gewinnen kann.
N : Menge der nichtterminalen Symbole;
mit N ∩ T = ∅
diese Zeichen werden ersetzt und dürfen in erzeugten Wort nicht vorkommen
S N : Startsymbol
Sei V := T ∪ N (das Vokabular).
V* ist wieder die Menge aller Wörter aus V
P ⊆ N x V* ist die Menge der Produktionen.
Für (u,v) ∈ P schreibt man auch u→v
Anschaulich kann man die rechte Seite durch die linke Seite ersetzen.

Die von der Grammatik G erzeugte Sprache ist L( G) := {w ∈ T* | S →* w }

Umfangreiche Rechnungen (Umformungen) lassen sich leichter bewältigen, wenn man länglichere Teilausdrücke durch neueinzuführende Symbole ersetzt. Am Ende der Rechnung werden diese Symbole wiederum durch den Teilausdruck ersetzt. Diese Symbole werden Termvariablen genannt. Dies wollen wir verallgemeinern:

Variable

Eine Variable ist ein Symbol, das durch Individuen eines Grundbereichs ersetzt werden darf. Dieser Grundbereich heißt Typ der Variable.

Die obigen Symbole sind Variablen mit dem Grundbereich Terme2 , also Termvariablen. Es soll aber nicht zulässig sein, Termvariablen etwa durch beliebige Formeln zu ersetzen.
(Terme bestehen als Konstanten, Variablen und Rechenoperationen. In atomare Formeln werden kommen Terme und Relationen vor. Atomare Formeln werden mit logischen Operationen und Quantoren zu Formeln verknüpft. Formeln sind also Aussagen bzw. Aussageformen, wenn noch freie,d.h ungebundene Variablen vorkommen).
Stellt man für Formeln eine Grammatik auf, so wird man ein nichtterminales Symbol haben, das die Terme repräsentiert. Dieses Termsymbol kann man auch als Startsymbol einer Teilgrammatik auffassen.
Da liegt folgende Definition nahe:

Wortvariable vom Typ eines Nichtterminalsymbols
  1. Sei G=(T,N,P,S) eine Grammatik und N ∈ N ein Nichtterminalsymbol.
    Eine Wortvariable ω vom Typ N ist ein Symbol, das durch Wörter der Menge
    L(G,N):={w ∈ T* | N → * w} ersetzt werden darf.

    Ω sei die Menge aller Wortvariablen beliebigen Typs.
    Es gelte Ω ∩ ( T N) = ∅

    Die Funktion Typ: Ω → N liefere den Typ einer Wortvariablen 3 : Typ(ω)=N
    ΩN := { ω ∈ Ω | Typ(ω) = N } sei die Menge aller Wortvariablen vom Typ N
    Die Typfunktion werde so auf Wörter mit Wortvariablen erweitert, daß im Wort jede Wortvariable durch das Nichtterminalsymbol ersetzt wird, dessen Typ sie hat:
    Typ:( T ∪ Ω)*V*
    Typ(w)=v ⇒ i=1,...,|w|: ((wi T ⇒ wi = vi) ∧ (wi ∈ Ω ⇒ vi =Typ(wi))) ∧ |w|=|v|

  2. GΩ ist die Erweiterung der Grammatik mit den Wortvariablen. Diese Grammatik entsteht durch Erweiterung der Grammatik G durch zusätzliche Produktionen, in denen die Nichtterminalsymbole durch Wortvariablen ihres Typs ersetzt werden:
    T := TG ∪ Ω
    N := NG
    P := PG ∪ { N → ω | N ∈ NG ∧ ω ∈ ΩN }
    S := SG

LΩ = L(GΩ) sei die Erweiterung der Sprache mit den Wortvariablen.

Substitutionen

Die Ersetzung von Wortvariablen in einem Wort aus LΩ durch Wörter entsprechenden Typs nennt man Substitution.

Eine Substitution

σ wird auf einer Menge A ⊆ Ω von Wortvariablen definiert.
Es muß gelten
4: ∀ a ∈ A: σ(a) ∈ LΩ(G,N)

Terminalsymbole bleiben stehen: ∀ t ∈ T : σ(t)=t

Für Wörter w ∈ (T∪Ω)* : σ(w) = Xi=1,...,|w|σ(wi)
(X sei die wiederholte Konkatination ähnlich dem Summenzeichen Σ für die Summation : Xi=1..n wi := w1w2...wn

Bemerkung: Man kann Substitutionen als Funktionen von Variablen in Wörter auffassen und die Erweiterung als Funktion von Wörtern in Wörtern:
σ : LΩ → LΩ

Substititionen von Wörtern mit Wortvariablen bleiben in der Sprache

σ(w)=v ⇒ Typ(w) →* Typ(v)

Die Konstruktion aus Wortvariable vom Typ eines Nichtterminalsymbols und Substitutionen stellt dies sicher.

Generalisierung von Wörtern

Wenn durch Substitution von Teilwörtern durch Wortvariablen mehrere verschiedene Wörter gleich gemacht werden können, so kann man sagen, daß sie die gleiche Struktur haben. Dann kann eine Äquivalenzrelation "Strukturgleichheit" eingeführten. Damit kann man auch begründet von Abstraktion sprechen. Das durch die Substitution mit den Wortvariablen erhaltene Wort kann man dann abstraktes Wort nennen.

Wenn durch die Rücksubstitution die Variablen wieder durch Teilwörter ersetzt werden, kann man das auch als Spezifikation (Artbildung) auffassen. Damit hat man nach der ursprünglichen Wortbedeutung den Begriff "Art", und dazu gehört ja auch nach der antiken Definitionslehre (vgl. [Wede92] S.31) eine Gattung.
Damit haben wir die Art-Gattungs- oder Subordinationsbeziehung zwischen Wörtern .

Diese Beziehung von Art zur Gattung wird oft Generaliserung und die von Gattung zur Art wird auch Spezialisierung genannt.

Allgemeines Generalisierungsproblem [Knight89]

Gegeben seien zwei Objekte 5 x und y.
Gesucht ist ein drittes Objekt z von denen sowohl x als auch y Instanzen sind

Die Ersetzung von Teilwörtern durch Wortvariablen wird laut Knight "Antisubstitution" genannt.

Antisubstitution

Die Umkehrungen von Substitutionen heißen Antisubstitutionen.

Da es nicht sinnvoll ist, willkürlich Teilwörter aus Wörtern einer Sprache zu ersetzen, gelten die selben Bedingungen wie für Substitutionen:

Bedingung für Antisubstitutionen

Sei G eine Grammatik, w ∈ L(GΩ) und γ eine Antisubstitution.

Es sollte gelten:
Typ(γ(w)) →G*Typ(w)

Generaliserbarkeit von Wörtern

Seien v,w ∈ LΩ. v und w sind generalisierbar (generalizable), wenn eine Antisubstitution γ existiert, so daß γ(v) = γ(w).

γ heißt dann Generalisierer von v und w.

Die Generalisierung von Wörtern ist an sich nichtssagend, weil zwei Wörter v und w immer durch eine Antisubstitution γ = {v → ζ , w → ζ } auf triviale Weise generalisiert werden können (Typ(ζ) = S).
Es interessiert aber, welcher Generalisierer am meisten Struktur übrig läßt:

speziellster Generalisierer (MSG)

Ein Generalisierter γ von v,w heißt der speziellste Generalisierer (most spezific generalisizer), falls es für jeden anderen Generalisierter η eine Antisubstitution ν gibt, so daß

νγ(s) = η(s)

Intuitiv enthält die speziellste Generalisierung von zwei Wörtern die Information, die in beiden Wörtern enthalten ist und führt neue Wortvariablen dort ein, wo die Wörter voneinander abweichen.

Bemerkung: In [Reyn70] wurde die Existenz für einen eindeutigen speziellsten Generalisierer für first-order Terme bewiesen und ein Algorithmus zur Ermittlung angegeben. Plotkins hat unabhängig in [Plotk70] einen ähnlichen Algorithmus entdeckt.

Mit diesem können wir nun formal die Abstraktion "Struktur" einführen:

Nach [Lor87] S. 163 ist die Abstraktion die Beschränkung auf invariante Aussagen bezüglich einer Äquivalenzrelation ˜.

Strukturabstraktor

Sei also σ der speziellster Generalisierer der Wörter w1 und w2.

Dann haben wir die Äquivalenzrelation

w1 ˜σ w2 :⇔ σ(w1) = σ(w2)

Für alle bzgl. ˜σ invarianten Ausgeformen A mit

w1 ˜σ w2 ⇒ (A(w1) ⇔ A(w2)
redet man dann nur noch mit dem "abstrakten Wort" σw1

Diesen speziellsten Generalisierer σ kann man nun "Strukturabstraktor" nennen.

Praktische (und theoretische) Anwendungen

Aufstellung und Implementierung von Hierarchieen

Tabellenspezifikation von strukturgleichen Wörtern

Diese mit der oben beschriebenen Methode erhaltenen Beziehungen kann man auch ausnutzen, um die Wörter übersichtlich aufzuschreiben:
Man schreibt erst das abstrakte, generalisierte Wort auf, und dann die Wertetabelle der Substitutionsfunktionen, die das abstrakte Wort zu den spezielleren Wörtern substituiert.

Beispiel: Die Tabelle 1 im Abschnitt 3.4 in [Weber93] dient hier als klassisches Beispiel aus der Strömungsmachanik:
Die allgemeine Transportgleichung in koordinatenfreier Form mit den Termvariablen φ,Γφ, qφ :

Die verschiedenen Transportgleichungen ergeben sich aus folgender Tabelle:

Name

φ

Γφ

qφ

Massenerhaltung

1

0

0

U-Impulserhaltung

U

μ

V-Impulserhaltung

V

μ

Temperaturgleichung

T

0

Weitere praktische Beispiele findet man in [Weber93] .

Umsetzung in Klassen und Implementierung bei Formeln

Jede abstrakte Formel wird in eine Klasse geschrieben. Manchmal ist es sinnvoll, für eine Formel eine eigene Klasse zu bilden, auf alle Fälle gehört die Formel zu irgendeiner Klasse.

Die zu substituierenden Variablen mit Name V der abstrakten Formel in der Oberklasse ergeben eine virtuelle Operation namens berechneV , die in einer Unterklasse realisiert wird.
In der abstrakten Formel in der Oberklasse werden die Vorkommen der Variablen V dann durch Aufrufe der Operation berechneV ersetzt.

Der Vorteil liegt in der Wiederverwendung von Programmteilen, die nur einmal geschrieben und ausgetestet werden brauchen.

Leider wird diese Implementierungstechnik einen nicht vertretbaren hohen Laufzeitaufwand verursachen, da die konkreten Funktionen zur Laufzeit bestimmt und dann aufgerufen werden müssen (virtuelle Funktion in C++). In C++ erfolgt dies zwar sehr effizient (Zugriff auf Feld von Funktionszeiger über Index, dann Aufruf), dies ist jedoch viel mehr als die direkte Ausführung des Codes.
Dies kann jedoch einfach vom Compiler optimiert werden, wenn er die Hierarchieen einebnet, d.h in einer konkreten Klasse die Variablen und Funktionen der Oberklassen implementiert, so daß die Vererbung entfällt.

Designalternativen bei der Aufstellung von Hierarchieen

Wenn man einen Algorithmus oder einen Typ auf verschiedene Weise implementieren will, kann man oft eine gemeinsame Aufrufschnittstelle herstellen. Hier liegt also wieder eine Abstraktion vor.

Dies kann man nun auf 3 verschiedene Arten realisieren:

  1. virtuelle Funktion / Zeiger auf Funktionen

    Hier werden Designalternativen als Unterklasse im objektorientierten Sinne formuliert und entsprechend instanziert.

    Vorteile:

    Nachteile:

  2. Fallunterscheidung mit if oder switch/case
  3. Hier beschreiben Variablen welcher Algorithmus gewählt wird, die dann an Stellen, an den sich die Alternativen unterscheiden, auf die verschiedenen Alternativen verzweigt wird (vgl. Giantsimulator Modul wuerfel.c von Ronald Lange, verschiedener Kraftalgorithmus bei Molekulardynamikprogramm)

    Vorteile:

    Nachteile:

  4. Entscheidung zur Link- oder Ladezeit
  5. In diesem Fall werden separate Module geschrieben, die dann entsprechend zusammengelinkt werden.

    Voraussetzung ist, daß im selben Programm nur eine Alternative benötigt wird.

    Hierzu empfiehlt es sich, die Verzeichnisstruktur des Quellcodebaumes als Vererbungshierarchie anzulegen. Es gibt Quellcodedateien, die in jeder Alternative neu Übersetzt werden müssen. Dies Kann man in UNIX-Dateisystemen dadurch erreichen, daß man einen sog. Softlink zum Original setzt, der nach dem Übersetzen wieder entfernt wird.

    Mit C-Präprozessordirektiven (

    #ifdef BEDINGUNG
      //... 
    #else
     ...
    #endif
    
    ) kann man leicht voneinander abweichende Programmteile verschiedener Versionen in demselben Modul realisieren, was dann je nach benötigter Version verschieden übersetzt wird.

    Vorteile:

    Nachteile:

Verallgemeinerung auf beliebige Programmtexte

Die "Wörter" aus dem Theoretische Fundierung können natürlich auch beliebige Funktionen bzw. Prozeduren oder sogar ganze Programme sein.

Für den Bereich der parallelen technisch-wissenschaftlichen Programme liegt die Idee nahe, die Parallelitätsstruktur aus den Programmtexten zu abstrahieren.

Funktionale Abstraktion

Das Wiederverwenden von gemeinsamen Teilwörtern ist nichts anders wie die Funktionale Abstraktion, mit dem praktischen Zweck, Codefragmente wiederbenutzen zu können (Vor allem wichtig bei Änderungen (Softwarewartung): Eine Sache soll an einer Stelle geädert werden können)

Rahmenwerkabstraktion (Framework-Abstraction)

Bei der ersten Version dieser Arbeit 1994 war diese noch nicht allgemein bekannt. Im grundegenommen handelt es sich aber um strukturgleiche Programme/Systeme im Sinne dieser Arbeit. Es werden die abstrakten Zusammenhänge programmiert, die dann durch konkrete Einschübe detailiert werden.

Begriffsbildung in Formalwissenschaften, besonders in der Mathematik

Bei der genaueren Betrachtung der Mathematik stellt man fest, daß z.B Begriffe wie "Gleichungssystem","lineares Gleichungssystem" mit Hilfe der Strukturgleichheit gebildet werden.

Ein weiteres Beispiel sind die oben erwähnten Transportgleichungen. Der aufmerksame Leser wird viele weitere Beispiele in der mathematischen Literatur finden.

Wiederverwendung von Beweisen/Rechnungen

In Grammatiken, Wortvariablen und Substitutionen wurde als Motivationsbeispiel erwähnt, wie man sich durch die Einführung von Wortvariablen bei formalen Rechnungen und Beweisen die Arbeit übersichtlicher gestalten und somit vereinfachen kann. Mit der obengenannten Anwendung kann man sich Arbeit ersparen.

In [Weber93] wurde (wie auch schon in der strömungsmechanischen Literatur wie [Plotk70]) zuerst solange wie möglich mit der allgemeinen Transportgleichung (bei der Diskretisierung) gerechnet, dann erst mit den speziellen weitergerechnet.
Es wurde auch so lange wie möglich koordinatenfrei (mit Vektoren, Divergenz,...) gerechnet, und erst möglichst spät der zweidimensionale kartesische Fall betrachtet.

Semantik von strukturgleichen Formeln

Strukturgleichheit in der Aussagenlogik

Sei A seine Aussagenform in der Aussagenlogik und und B1,...,Bk Aussageformen.
B sei diejenige Aussageform, die aus A entsteht, wenn man simultan alle Vorkommen von durch Bj ersetzt.

Dann gilt: Wenn A eine Tautologie ist, so ist auch B Tautologie
(Strehl ,Kap. I Abschnitt 15 S. 15)

Bemerkung : Das simultane Ersetzen ist wichtig:
z.B ist A(p1 →(p2) →p1)) eine Tautologie. Das simultane Ersetzen von p 1 durch p 2 liefert die Tautologie (p 2 →(p 2 →p 2))
Ersetzt man jedoch nur das erste Vorkommen von p 1 , so erhält man (p 2 →(p 2 →p 1)), was keine Tautologie mehr ist (man bewerte p 1 mit "falsch" und p 2 mit "wahr").
([Strehl] , Kap. I, Abschnitt 17)
Es ist also Vorsicht angesagt!

Äquivalenzbedingung für strukturgleiche Ausdrücke in der Aussagenlogik

Seien A,A',B,B' Ausgabeformen, wobei A' aus A entsteht, in dem man einige (also beliebig viele) Vorkommen von B in A durch B' ersetzt. (A und A' sind also strukturgleich).

Dann gilt: wenn B äquivalent mit B' ist, so ist auch A äquivalent mit A'.
([Strehl], Kap. I, Abschnitt 16)

Ideen zum Konzept der Teilgrammatik

Grundlegende Definitionen

Teilgrammatik

Eine Grammatik Gt = ( Tt , Nt , Pt , St) ist Teilgrammauik von G =( T , N , P , S) , als Formalzeichen Gt G :

Tt T
Nt N
Pt ⊆ P
St N

Die terminalen und nicht-terminalen Symbole sowie die Produktionen müssen also ein Teil der Gesamtgrammatik sein und das Startsymbol der Teilgrammatik ist ein Nichtterminales Symbol der Gesamtgrammatik.

Beispiel: Die Grammatik der arithmetischen Ausdrücke einer Programmiersprache ist eine Teilgrammatik der Grammatik der Programmiersprache.

Bedingung für Enthaltensein der Sprache der Teilgrammatik in Sprache einer Grammatik

S →G* N ∧ Gt G ⇒ L(Gt) ⊆ L(G)

Beweis: ⇒ trivial.
Der Fall ⇐ ergibt sich aus der Tatsache, daß die Wörter der Teilgrammatik Teilwörter der Wörter der Grammatik sind. (Teilsprache und Teilgrammatik sind also grundverschieden.)

Konstruktion einer Teilgrammatik

Sei G =( T , N , P , S) eine Grammatik und N N ein Nichtterminalsymbol.
Gesucht wird die Teilgrammatik GtN = ( Tt , Nt , Pt ,N) ⊆ G .

Hilfsdefinitionen:

L'( G,N):={w ∈ V* | N →* w} Menge der aus N ∈ N erzeugbaren Symbolfolgen

B(w) := { wi | i=1,...|w|} : Menge der Symbole im Wort w ∈ V*

W ⊆ P( V*); : Erweiterung auf Wortmengen.

Die Teilgrammatik Gt N ergibt sich dann:

Tt = B(L'( G ,N)) ∩ T
Nt = B(L'( G ,N)) ∩ N
Pt = P Nt x Vt* mit Vt := Nt Tt
St
= N

(Wie man sofort sieht, ist die Teilgrammatiksbedingung erfüllt.)

Diese Konstruktion ist aber für die Theoretiker, denn die praktischen Beispiele sind einfach ersichtlich.

Anwendung im (objektorientierten) Compilerbau

Vorbild Scanner für Teilgrammatikparser

Im Compilerbau ist es üblich, die Schlüsselwörter, Ganzzahl und Fliesskommazahlen als terminale Zeichen zu betrachten. Der Parser empfängt diese abstrakten Eingabesymbole von einem Scanner. Damit wird erreicht, daß der Parser einfacher wird, da seine Grammatik kleiner ist.
Jedes vom Scanner erkannte Symbol stellt eine einfache Teilgrammatik dar.
Könnte man nun Teile des Scanners allgemein verfügbar machen, so sparte man sich z.B. Funktionen, die Konstanten aus einer Zeichenkette konvertieren.
Verschiedene Programmiersprachen haben die selbe Syntax für diverse Konstanten. Damit könnten Compiler für diese Programmiersprachen in einem Rechensystem Teile von ihren Scannern gemeinsam haben.

Dieses Vorgehen kann verallgemeinert werden. Beispielsweise unterschieden sich arithmetische Ausdrücke nur unwesentlich in diversen Programmiersprachen. Die arithmetischen Ausdrücke werden z.B in einem Tischrechnerprogramm (Tabellenkalkulation, Datenbanksystem,...) auch eingesetzt.

Teilgrammatikparser sind Kandidaten für Objekte in einem Compiler

Da Teilgrammatiken wie oben angedeutet, mehrfach verwendet werden können, ist es sinnvoll sie als Objekte in einem objektorientierten Compiler zu definieren.

Ein Compiler ruft dann bei der Analyse zur Identifikation eines Unterkonstruktes eine Parserroutine einer Teilgrammatik auf.

Bei der Compilerkonstruktionsmethode des rekursiven Abstiegs von N. Wirth entstehen diese Teilgrammatikparser automatisch.

Bei attributierten Grammatiken werden die Terminal- und Nichtterminalsymbole mit Attributen versehen. Somit ist also naheliegend, diese als Klassen im objektorientierten Sinn aufzufassen. Diese aus den Symbolen induzierten Klassen sind dann auch Bestandteil der internen Strukturen das Compilers.

Wiederverwendung semantischer Konstrukte und Optimierungsroutinen

Die internen Strukturen, die ein Compiler zur Analyse und Optimierung verwendet, sind Kandidaten für Klassen im Sinne der objektorientierten Programmierung. Wenn Sprachen gemeinsame Teilgrammatiken haben, dann können sie auch die gleichen internen Strukturen verwenden.

Auch wenn verschiedene Sprachen verschiedene Teilgrammatiken für ein Konzept wie z.B `arithmetischer Ausdruck' haben, so könnten in Compilern ähnliche interne Strukturen haben.

Viele Optimierungsroutinen, die auf diesen Strukturen arbeiten, können dann geteilt werden.

Literatur

[Knight89]
Knight,K: "Unification: A Multidisciplinary Survey" ACM Computing Surveys Vol 21 No.1 März 1989
[LiGu86]
Liskov,B., Guttag,J.: "Abstraktion and Specification in programm development",
MIT Press Cambridge,Mass. 1986
[Lor64]
Lorenzen,P:"Differential und Integral" Akademische Verlagsgesellschaft Frankfurt 1964
[Lor87]
Lorenzen,P.:"Lehrbuch der konstruktiven Wissenschaftstheorie", Mannheim,Wien,Zürich: BI Wissenschaftsverlag 1987
[Mitt80]
Mittelstrass, J.:"Enzyklopädie Philosophie und Wissenschaftstheorie",Mannheim u.a. Bibliographisches Institut 1980/84
[Plotk70]
Plotkin, G. "A note on inductive generalization"
Mach. Intell. 7 1970 (Verweis aus [Knight89])
[Reyn70]
Reynolds J. "Transformal systems and the algebraic structure of atomic formulars", Mach. Intell. 7 1970 (Verweis aus [Knight89])
[Rumb91]
Rumbaugh,J.: "object-oriented modeling and design", Englewood Cliffs, NJ u.a. Prentice-Hall International 1991
[Seiffert83]
Seiffert, H.: "Einführung in die Wissenschaftstheorie",10. Auflage, Beck München 1983
[Strehl]
Strehl: "Logik und Berechenbarkeit II" Vorlesungsscriptum zur gleichnamigen Vorlesung, IMMD I Universität Erlangen Nürnberg
[Strou92]
Stroustrup, B.: "Die C++-Programmiersprache"2. Aufl.,Bonn u.a, Addison-Wesley, 1992
[Weber91]
Weber,R.; "Ein formales Modell zur Beschreibung von Vererbungsmechanismen in objektorientierten Programmiersprachen" Studienarbeit IMMD IV; 1991
[Weber93]
Weber,R: "Objektorientierte Programmierung für strömungsmechanische Probleme" Diplomarbeit 8/93 IMMD IV 1993
[Wede92]
Wedekind,.H : "Objektoriententierte Schemaentwicklung, ein kategorialer Ansatz für Datenbanken und Programmierung", BI-Wissenschaftsverlag Mannheim/ Leipzig /Wien/Zürich 1992

1. Der Begriff "Menge" sei schon als konstruiert vorausgesetzt. Alternativ könnte man auch eine naive Ansammlung von Zeichen annehmen. Ebenso seien schon die Menge aller Wörter A * aus dem Alphabet A, die Relationen, die transitive Hülle einer Relation und Funktionen schon konstruiert.

2. Der Begriff `Term' müßte eigentlich eingeführt werden (z.B wie in Lor64 ), dies kann mit Hilfe einer Grammatik geschehen; der Leser wird aber sicher mathematisch vorgebildet sein, so daß hier darauf verzichtet werden kann.

3. Anstelle der Definition einer Funktion könnte man auch den Typ als Attribut der Variable sehen.

4. Man entschuldige die Quantorenschreibweise. Ein großes wäre viel schöner. Es ist doch schlimm, daß Texteditoren die Autoren oberfächlich in bestimmte wisschenschaftstheoretische Richtingen zu drücken versuchen ...

5. Hier wird der Begriff "Objekt" im umfassenden Sinne benutzt und nicht im Sinne der objektorientierten Programmierung