3.1 Spezifikation

Werbung
3 Spezifikation und Verifikation
3.1
1
Spezifikation (specification) einer Prozedur/Methode/Routine/...
= Beschreibung ihres Kopfes („Syntax“)
und ihres von außen sichtbaren Verhaltens („Semantik“)
- unter vollständiger Abstraktion von ihrer Implementierung (Rumpf)
Verifikation (verification) einer Prozedur/Methode/Routine/...
= Nachweis, dass die Implementierung der Spezifikation genügt
und zwar nicht durch Testen - denn das ist zum Scheitern verurteilt.
( Dijkstra (1972): „Testing can be used to show the presence of bugs,
but never to show their absence!“)
3.1
2
3.1 Spezifikation
beschreibt für eine Prozedur/Methode/Operation/Routine/...
 ihren Kopf (Signatur),
„Syntax“
 ihre Voraussetzung (precondition)
betr. nichtlokale Variable und Parameter
 ihren Effekt (postcondition)
„Semantik“
betr. nichtlokale Variable und Parameter
 ihr Ergebnis (result) (falls nicht void)
beschreibt für Anweisungen lediglich  und .
3.1
3
Warum spezifizieren ?
 Dokumentation/„Gebrauchsanweisung“ für fremde Anwender
 Vorgabe für die Implementierung
Wie spezifizieren ?
 Umgangssprache und/oder
 mathematische Formelsprache und/oder
 formale Sprache
3.1
4
Beispiel für Spezifikation einer Funktionsprozedur:

double sqrt(double x)
 Voraussetzung x ≥ 0
 kein Effekt
 Das Ergebnis w hat die Eigenschaften | w2 - x | < ε , w ≥ 0 .
Beachte: die Spezifikation ist unvollständig („lose“):
 w wird nicht eindeutig festgelegt;
 das Verhalten bei nicht erfüllter Voraussetzung
ist nicht festgelegt.
3.1
5
3.1.1 Formale Spezifikation von Anweisungen
mittels Aussagenlogik/Prädikatenlogik
Zur Erinnerung (1.3): eine Anweisung überführt
einen Anfangszustand z in einen Endzustand z‘.
Beispiel, zunächst umgangssprachliche Spezifikation:
„Die Anweisung S operiert auf dem Feld a = new int[n] ,
das mindestens eine positive Zahl b enthält.
Nach Ausführung von S sind alle Feldelemente gleich b.“
3.1
6
Formal:
Zustand:
final int[] a = new int[n];
Voraussetzung:
P(a) ≡ ∃i∈[0,n-1] a[i] > 0
Effekt:
Q(a, a‘) ≡ ∃i∈[0,n-1] ( a[i] > 0 ∧ ∀k∈[0,n-1] a‘[k] = a[i] )
( a‘ = „der neue Wert von a“)
oder
Q('a, a) ≡ ∃i∈[0,n-1] ('a[i] > 0 ∧ ∀k∈[0,n-1] a[k] = 'a[i] )
( 'a = „der alte Wert von a“)
oder
Q(A, a) ≡ ∃i∈[0,n-1] (A[i] > 0 ∧ ∀k∈[0,n-1] a[k] = A[i] )
( A = „der alte Wert von a“)
3.1
7
Formalsprachlich - z.B. mittels Haskell:
Zustand:
[Int]
Voraussetzung:
p = any(>0)
-- p a = ...
Effekt:
q a = any(\ai -> ai>0 &&
all(\ak -> ak==ai) a)
-- q a 'a = ... !
(Zur Erinnerung:
3.1
any, all :: (t->Bool) -> [t] -> Bool
any p = or . map p
all p = and. map p
)
8
? Alternative:
Neuer Zustand als Ergebnis einer Zustandsüberführungsfunktion ?
(Vgl. denotationelle Semantik, 1.3)
f a = [ rep(length a)x | x <- a, x>0 ]
 bestimmt Lösungsmenge,
 stellt ein Verfahren zur Gewinnung dieser Lösungen dar,
 d.h. gibt die neuen Zustände explizit an statt sie implizit zu charakterisieren.
Vorteil: prototypische Problemlösung, „ausführbare Spezifikation“
Nachteile: meist aufwendiger und schwerer verständlich,
u.U. gar nicht praktikabel (z.B. y = sqrt(x); )
3.1
9
3.1.2 Eigenschaften von Spezifikationen
Notation:
terminierende Anweisung A
Zustandsmenge Z
Spezifikation (P,Q) (Voraussetzung und Effekt)
Sonderfälle:
3.1
(T,Q)
A bewirkt Q „ohne Voraussetzung“
(P,T)
A bewirkt „irgendetwas“ (egal ob P erfüllt ist)
(F,Q)
A bewirkt „irgendetwas“ (da F nicht erfüllbar)
(P,F)
fehlerhafte Spezifikation (da F nicht erfüllbar)
(P,P)
(P≠T,F) P ist Invariante unter A
10
Def. 1: (P,Q) heißt konsistent (consistent), wenn
 ∃z∈Z P(z) , d.h. P ist erfüllbar
 ∀z∈Z ( P(z) ⇒ ∃z‘∈Z Q(z,z‘) )
PQ(z)
schwächste Voraussetzung für Q
(weakest precondition)
d.h. wenn P erfüllt ist, ist Q erfüllbar
Def. 2: (P,Q) heißt vollständig (complete), wenn
∀z∈Z ( P(z) ⇒ | { z‘ | z‘∈Z , Q(z,z‘) } | = 1 )
d.h. der Folgezustand ist stets eindeutig festgelegt.
3.1
11
Beispiel:
Z = R , (P,Q) ≡ ( z > 0 , | z - z‘2 | < ε )
 ist konsistent, weil
 es existieren z∈R mit z>0.
 für jedes z>0 erfüllt z‘ = √z sogar | z - z‘2 | = 0
Schwächste Voraussetzung ist
PQ(z) ≡ ∃z‘∈R | z - z‘2 | < ε
≡ z>-ε
d.h. z>0 ist unnötig stark, z.B. z≥0 genügt auch
 ist nicht vollständig, weil
 verschiedene Näherungswerte sind erlaubt,
 mit jedem z‘ ist auch -z‘ erlaubt.
3.1
12
Def. 3:
(P1,Q1) heißt stärker als (P2,Q2)
- in Zeichen (P1,Q1) ⇒ (P2,Q2) wenn Q1 ⇒ Q2 ∧ P1 ⇐ P2 ;
d.h. wenn eine Anweisung der Spezifikation (P1,Q1)
genügt, dann genügt sie auch der Spezifikation (P2,Q2) :
{ P2 } { P1 } A { Q1 } { Q2 }
3.1
13
3.1.3 Spezifikation von Prozeduren
Zur Erinnerung: folgende Informationen sind anzugeben:
 Kopf (Signatur),
„Syntax“
 Voraussetzung (precondition)
betr. nichtlokale Variable und Parameter
 Effekt (postcondition)
„Semantik“
betr. nichtlokale Variable und Parameter
 Ergebnis (result) (falls nicht void)
... zwar umgangssprachlich und/oder formal und/oder
formalsprachlich - und eventuell mit Beispielen.
3.1
14
Dokumentation einer Prozedur besteht aus
 Problembeschreibung
 Spezifikation - abstrahiert von der Implementierung
 Beschreibung des Lösungsverfahrens, z.B.
„Einschachtelungsverfahren“ für ein Suchproblem
 Kommentare im Code
Häufig wird nicht nur , sondern auch    im Code untergebracht.
Java:
Standardisierte Kommentare erlauben Erzeugung einer
separaten HTML-Dokumentation mit javadoc MyClass.java
 http://java.sun.com/j2se/javadoc/
3.1
15
/**
* Documented class example
* <br>
* <br>Time of day
*/
public class Time { // non-public items will remain hidden
public int hrs, min;
/**
* Delivers time of day in readable format.
* <br>
* <br><b>pre: </b> -* <br>
* <br><b>post:</b> -* <br>
* @param ampm
asks for "hh.mm am/pm" or "hh:mm" format
* @return
the time in desired format,
*
e.g., "5.30am" or "12.15pm" or "1.0pm"(!) or "17:50"
* <pre>
* | ampm
= if hrs<12 then show hrs ++ "." ++ show min ++ "am"
*
else if hrs==12 then "12." ++ show min ++ "pm"
*
else show(hrs-12) ++ "." ++ show min ++ "pm"
* | otherwise = show hrs ++ ":" ++ show min
* </pre>
**/
public String time(boolean ampm) {.....}
.....
.....
/**
* Advances time of day by one minute.
* <br>
* <br><b>pre: </b> -* <br>
* <br><b>post:</b>
* <pre>
* | min == 59 = min' == 0 &&
*
if hrs == 23 then hrs' == 0 else hrs' == hrs+1
* | otherwise = hrs' == hrs && min' == min+1
* </pre>
**/
public void step() {..... }
.....
3.1
17
.....
/**
* Sets time of day.
* <br>
* <br><b>pre: </b>
* <pre>
* 0 <= h && h < 24 &&
-- else "hours?"
* 0 <= m && m < 60
-- else "minutes?"
* </pre>
* <b>post: </b>
* <pre>
* hrs' == h && min' == m
* </pre>
* @param h
hours
* @param m
minutes
* @throws Exception
**/
public void set(int h, int m) throws Exception { ..... }
}
3.1
18
Konvention:
In der Spezifikation nicht erwähnte
Variable werden nicht verändert !
Beispiel ohne Variable - Effekt nur über Parameter:
/** move element from one stack to another
* pre: a /= []
* post: a'==tail a && b'==head a : b
*/
void move(Stack a, Stack b) {..... }
Bemerkungen:
- Typ Stack („Stapel“) sei als Liste spezifiziert.
- Spezifikation benutzt dereferenzierte a und b.
3.1
19
Spezifikation von Funktionsprozeduren:
entweder: zusätzlich zur Effektbeschreibung wird
der Ergebniswert explizit beschrieben
oder:
zusätzlich zur Effektbeschreibung wird der
Ergebniswert implizit charakterisiert - z.B. durch
ein Prädikat über die Pseudovariable result
oder:
3.1
Q charakterisiert zusammenfassend Effekt und result
20
Verschiedene Parameter-Mechanismen bei
T p( M X x) :
M = IN - Wertparameter:
Die Effektbeschreibung sollte nicht x' enthalten
- da irrelevant nach Beendigung der Prozedur.
M = OUT - Ergebnisparameter:
Die Spezifikation sollte sich nicht auf x beziehen
- da irrelevant für die Ausführung der Prozedur.
M = IN OUT - Wert/Ergebnisparameter
M = VAR - Variablenparameter
Keine Einschränkung.
3.1
21
Herunterladen