Grundlagen der Informatik I “Programmierung”
Grundlagen der Informatik I “Programmierung”
Grundlagen der Informatik I “Programmierung”
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Die Routine r muß natürlich eine Routine <strong>der</strong>jenigen Klasse sein, zu <strong>der</strong> das durch den qualifizierenden<br />
Ausdruck beschriebene Objekt gehört, und für die aufrufende Klasse überhaupt verfügbar sein, also nicht<br />
durch selektiven Export von <strong>der</strong> Benutzung ausgeschlossen sein. Bei mehrstufiger Qualifizierung gilt dies für<br />
den ganzen Weg von <strong>der</strong> aufrufenden zur definierenden Klasse.<br />
Eine entfernte Initialisierung <strong>der</strong> Art a.!!b o<strong>der</strong> a.!!b.init(Ausdruck1,...,Ausdruckn) ist übrigens<br />
nicht erlaubt. Die Initialisierung von Komponentenobjekte eines Objektes ist – wie die Zuweisung von Werten<br />
– ein Privileg, dessen allgemeine Freigabe dem Geheimnisprinzip wi<strong>der</strong>sprechen würde. Die Klasse, welche ein<br />
feature b von einem Klassentyp bereitstellt, sollte auch explizit eine Routine init b bereitstellen, wenn die<br />
Initialisierung von b durch Kundenklassen erlaubt werden soll.<br />
4.3.2.3 Verifikation von Routinenaufrufen<br />
Die Verifikation von Prozeduraufrufen ist über das Kontraktmodell bereits weitgehend vorbereitet. Wir haben<br />
in Definition 4.2.3 auf Seite 141 festgelegt, daß wir eine Routine r als korrekt ansehen, wenn ihr Anweisungsteil<br />
Br die vereinbarten Vor- und Nachbedingungen einhält, also wenn für alle gültigen Argumente xr gilt<br />
{ prer(xr)} Br { postr(xr)}<br />
In den Vor- und Nachbedingungen dürfen außer den formalen Argumenten nur noch Funktionen, die von <strong>der</strong><br />
definierenden Klasse erreichbar sind, und – bei Funktionen – die Größe Result genannt sein. 24 Da in <strong>der</strong><br />
Routine die formalen Argumente und das (meist nicht explizit genannte) aktuelle Objekt <strong>der</strong> definierenden<br />
Klasse aber nur Platzhalter für die aktuellen Argumente und das tatsächlich zu bearbeitende Objekt sind,<br />
dienen diese in dem Kontrakt ebenso als Platzhalter. Bei <strong>der</strong> Verifikation eines Aufrufs müssen also nur die<br />
formalen Argumente gegen die aktuellen Argumente und das aktuelle Objekt gegen das im Aufruf angegebene<br />
Objekt ausgetauscht werden, um einen gültigen Satz über diesen Aufruf zu erhalten.<br />
Um dies präzise auszudrücken, müssen wir die Vor- und Nachbedingungen durch Prädikate beschreiben, <strong>der</strong>en<br />
freie Variablen Platzhalter für die formalen Argumente und das aktuelle Objekt sind. Ist die Prozedur r durch<br />
r(y1:T1,...,yn:Tn) is do ... end<br />
deklariert, so beschreiben wir ihre Vorbedingungen durch<br />
prer(y1,...,yn, actual)<br />
und ihre Nachbedingungen durch<br />
postr(y1,...,yn, actual),<br />
wobei actual die Rolle von Current übernimmt, also implizit vor jedem Prozeduraufruf innerhalb des Anweisungsteils<br />
von r steht, um das Objekt zu kennzeichnen, auf dem gerade gearbeitet wird. Für lokale o<strong>der</strong><br />
entfernte Aufrufe von r gelten dann folgende Sätze:<br />
• { prer(A1,...,An,Current)} r(A1,...,An) { postr(A1,...,An,Current)}<br />
Dabei kann Current durch Vereinfachungen wie<strong>der</strong> entfernt werden.<br />
• { prer(A1,...,An,entity)} entity.r(A1,...,An) { postr(A1,...,An,entity)}<br />
Der Prädikatentransformer ergibt sich entsprechend: kann bei einem Routinenaufruf entity.r(A1,...,An)<br />
die Nachbedingung als postr(A1,...,An,entity) ausgedrückt werden, so ist prer(A1,...,An,entity) die<br />
zugehörige schwächste Vorbedingung. Je nach Implementierung von r wäre prinzipiell eine noch schwächere<br />
Vorbedingung möglich. Da diese aber im Kontrakt nicht enthalten ist und sich die Implementierung von r–<br />
unter Einhaltung des Kontraktes – än<strong>der</strong>n darf, kann eine schwächere Vorbedingung nicht garantiert werden.<br />
24 Im Idealfall lassen sich die Vor- und Nachbedingungen komplett als Zusicherungen <strong>der</strong> zugehörigen require und ensure Klausel<br />
formulieren. Zuweilen ist es jedoch nötig, diese mithilfe <strong>der</strong> vollen Prädikatenlogik etwas präziser zu formulieren, als dies mit <strong>der</strong><br />
Zusicherungssprache von Eiffel – entsprechend <strong>der</strong> Diskussion in Abschnitt 3.7.4 – möglich ist.