• Keine Ergebnisse gefunden

Die vorliegende Arbeit ergab sich aus umfangreichen Programmier-, Lehr-und Forschungsaktivit¨aten rund um und mit dem seit 1987 an der TU Ber-lin entwickelten Opal-Compiler. Hauptziel der Entwicklung von Opal war der Nachweis, dass mit funktionalen Sprachen produktiv effizienter Code f¨ur große Softwaresysteme erzeugt werden kann. Als Beleg daf¨ur wurde der Opal-Compiler selbst inOpal programmiert. Die gleiche Zielsetzung wurde etwa zur selben Zeit auch mit anderen funktionalen Sprachen (z.B.Haskell) intensiv verfolgt. Die historische Wurzel f¨ur die algebraische Orientierung von Opal ist die M¨unchner CIP-Gruppe [BBD+81], w¨ahrendHaskell in Glas-gow eher aus der nicht weit entfernten Edinburgher ml-Szene entstand.

Die algebraische Orientierung vonOpalversprach zwar eine theoretisch fun-dierte Semantik, allein f¨ur die Namensaufl¨osung in der Signaturanalyse fehl-ten konkrete Implementierungshinweise. Im Laufe der Zeit entstand so auf evolution¨are Weise eine Signaturanalyse, die immer mehr Quellen korrekt analysierte, aber mittlerweile so komplex und unwartbar ist, dass weitere Fehler kaum mit vertretbarem Aufwand beseitigt werden k¨onnen. Allein aus pragmatischer Sicht erscheint eine Re-Implementierung fast kontraproduktiv, da die existierende Stabilit¨at des Opal-Compilers – t¨aglich von Hunderten von Studenten gew¨urdigt – nicht leicht wieder zu erreichen w¨are.

1.4.1 Beweisbarkeit

Im Vordergrund mehrerer Forschungsprojekte mit Opal, insbesondere zur korrekten Software Korso [W+92, BJ95], standen formale Methoden und die Vision von beweisbar korrekter Software. Opal wurde (mehrfach) zu einer Spezifikationssprache erweitert und im Projektrahmen eines verifizier-ten Fachsprachencompilers [EFP94] entstand ein rudiment¨arer Beweispr¨ufer, der allerdings nach Projektende nicht weiter verwendet wurde. Bei der im Korso-Projekt entwickelten Spezifikationssprache Spectrum [B+93] stan-den eine hohe Ausdrucksm¨achtigkeit (wide spectrum) [WDC+95] und eine Softwareentwicklungsmethodik [PW94] im Vordergrund. (In [BDDG93] wird eine Anwendung beschrieben.)

Die Besch¨aftigung mit Beweiswerkzeugen f¨uhrte mich 1994 zum Prototype Verification System pvs [OSR93b]. Mit diesem Beweiswerkzeug lassen sich unter anderem klassische Theoreme aus der Schulmathematik zur Arithme-tik, Aussagen- und Pr¨adikatenlogik formal beweisen. (Die strenge

Typisie-rung verhindert die FormulieTypisie-rung von Russell’s Paradoxon: {x | x ∈/ x} ist typfalsch.) Das Beweisen ist ziemlichintuitiv undErkenntnis f¨ordernd; die in-teraktiven Beweisschritte entsprechen etwa denen, die man von einem schrift-lichen Beweis aus einem Lehrbuch erwarten w¨urde. Offensichtliche Details, die vielfach selbst in sorgf¨altigen schriftlichen Beweisen unerw¨ahnt bleiben, werden weitgehend vollautomatisch gel¨ost. Gleichzeitig kann die totale Kor-rektheit jederzeit anhand derBeweiskette ¨uberblickt werden. (Die Beweisket-te muss l¨uckenlos und zyklusfrei sein: Zirkelschl¨usse sind also ausgeschlossen.) Die Spezifikationsprache pvs ist funktional-algebraisch und ¨ahnelt Opal in Syntax und Semantik auf eine fast erstaunliche Weise, wenn man den unab-h¨angigen Entwurf beider Sprachen ber¨ucksichtigt. Die Parametrisierung und Instanziierung mit Typen und Funktionen ist praktisch bis hin zur Schreib-weise identisch, die Datentypen haben in beiden Sprachen eine (algebraisch naheliegende)initiale Semantik; das Modul- und Annotationskonzept ist fast gleich: in pvs sind Theorien und Datentypen [OS97a] die Module. Dar¨ uber-hinaus unterst¨utzen beide Sprachen uninstanziierte Importe und Reexporte, problematische Aspekte, die in dieser Arbeit in Kapitel 7 genauer untersucht werden.

Die unterschiedliche Zielsetzung beider Sprachen bewirkte allerdings auch deutliche Unterschiede: in Opal sind die Funktionen i.A. partiell, w¨ahrend pvs mit Hilfe von Subtypen und abh¨angigen Typen (dependent types) die flexible Spezifikation von totalen Funktionen fordert; außerdem k¨onnen in pvs Funktionen nicht wechselseitig rekursiv definiert werden – eine f¨ur Im-plementierungssprachen durchaus l¨astige Beschr¨ankung. F¨ur eine bestenfalls halbautomatische eins-zu-eins ¨Ubersetzung zwischen Opal und pvs w¨are Folgendes zu ber¨ucksichtigen:

• Wechselseitig rekursive Funktionen ausOpalm¨ussten f¨urpvs zu einer einzigen rekursiven Funktion zusammengefasst werden; das w¨urde die Lesbarkeit reduzieren.

• Zu rekursiven Funktionen muss allein gem¨aß der Syntaxregeln vonpvs einTerminierungsmaß (measure), eine Beschreibung der Eingabegr¨ o-ße, angegeben werden.

• F¨ur partielle Funktionen muss inpvsder genaue Definitionsbereich (als Subtyp) spezifiziert werden.

• Nicht alle pvs-Funktionen sind ausf¨uhrbar, insbesondere die (starke) Gleichheit – ein essenzieller Teil der Logik – steht nicht unmittelbar f¨ur konstruktive Berechnungen zur Verf¨ugung.

1.4.2 Werkzeugintegration

Die relative ¨Ahnlichkeit von Opalundpvs f¨uhrte zu der ¨Uberzeugung, dass man mit einerreinen funktional-algebraischen Sprache in der Lage sein sollte, ausf¨uhrbaren Code zu erzeugen und zu verifizieren. Die automatische (und korrekte) Einbettung von verifiziertem Code in ein lauff¨ahiges Programm existiert praktisch nicht. Eine (z.B. mit pvs) vollst¨andig bewiesene Funkti-on – allein dieser Umstand ist selten – wird h¨ochstens manuell oder halb-automatisch in eine andere Programmiersprache ¨ubertragen, compiliert und ausgef¨uhrt; eine andere Semantik erh¨oht dabei zus¨atzlich die Wahrschein-lichkeit f¨ur Transformationsfehler. Der Erfolg desKids-Systems [Smi90] be-ruht sicherlich zum Teil darauf, dass Codererzeugung und Verifikation (bzw.

Korrektheit garantierende Transformationen) eng integriert sind und erst da-durch Synergie entsteht.

Die Entwicklung eines integrierten ¨Ubersetzungs- und Beweiswerkzeugs, die f¨urOpal angestrebt wird [Did97], erfordert erhebliches Know-how in Bezug auf ¨Ubersetzer- und Beweisertechniken, das zwar prinzipiell vorhanden ist, aber leider mehr oder weniger undokumentiert in verschiedenen Systemen (und K¨opfen) verborgen ist.

Um die Brauchbarkeit des Werkzeugs m¨oglichst fr¨uh pr¨ufen zu k¨onnen, bietet sich f¨ur ¨Ubersetzer dieSelbstapplikation an. Ein (brauchbarer) ¨Ubersetzer f¨ur eine (brauchbare) Sprache sollte in derselben Sprache programmiert werden k¨onnen und sich selbst ¨ubersetzen k¨onnen. (Und in diesem Sinne ist auch Opal brauchbar.) Das Bootstrapping-Problem daf¨ur ist bekannt.

F¨ur das Beweissystem ist nun interessant, wie weit es sich selbst beweisen kann. Damit steht die Konsistenz (soundness) der eigenen Logik auf dem Pr¨ufstand und k¨onnte maschinell mit einer Genauigkeit untersucht werden, die manuell bei weitem unerreichbar ist. (Vollst¨andigkeit ist nach G¨odel nicht gegeben, aber sein Satz zur Unvollst¨andigkeit der Logik w¨are formal beweis-bar.) Leider sind die meisten Beweissysteme schon ¨alter und nicht in der (reinen) Objektsprache ihrer Logik programmiert: pvsz.B. basiert auf Lisp und ist eben keine Implementierungssprache mit einem ¨Ubersetzer. ¨Uber die Implementierung von Beweissystemen in einerreinen funktionalen Program-miersprache wird in [Han99] berichtet.