1. Erste Schritte 2. Einfache Datentypen 3. Anweisungen und

Werbung
„ 5. Reihungen (Arrays)
„ 4. Verifikation
„ 3. Anweisungen und Kontrollstrukturen
„ 2. Einfache Datentypen
„ 1. Erste Schritte
II.1.4. Verifikation - 1 -
Semantik der Programmiersprache
II.1.4. Verifikation - 2 -
z Terminierung: Hält Programm immer an?
z Partielle Korrektheit: Falls Programm anhält, erfüllt es Spezifikation?
z Totale Korrektheit: Terminierung & Partielle Korrektheit
„ Verifikation: Mathematischer Beweis der Korrektheit
keine 100% Sicherheit
„ Testen: Überprüfung für endlich viele Eingaben
z natürliche Sprache
z grafische Sprachen (UML, ...)
z logische Sprachen (Z, VDM, ...)
„ Spezifikation: Angabe, was ein Programm tun soll
4. Verifikation
}
System.out.println("Die Fakultät ist " + res);
}
i = i - 1;
res = res * i;
while (i > 1) {
res = 1;
i = n;
public static void main (String [] arguments) {
int n = IO.eingabe(), i, res;
Fakultät
II.1.4. Verifikation - 3 -
}
i = i - 1;
res = res * i;
while (i > 1) {
res = 1;
i = n;
hilft für Programmentwurf und Programmierstil
II.1.4. Verifikation - 4 -
Wie beweist
man so etwas ?
Verifikation nötig bei sicherheitskritischen Anwendungen
„ Totale Korrektheit
Nach Ausführung ist res = n!
„ Partielle Korrektheit:
Programm hält an, weil i in jedem Schleifendurchlauf kleiner wird
„ Terminierung:
Programm berechnet (in res) Fakultät von n
„ Spezifikation:
Programm P
Verifikation
< true > P < res = n! >
II.1.4. Verifikation - 5 -
Hoare-Kalkül: 7 syntaktische Regeln zur Herleitung von
Korrektheitsaussagen
„ Partielle Korrektheit ist semantische Aussage
„ Bsp:
dann gilt hinterher Nachbedingung ψ.
und Ausführung von P terminiert,
Wenn vor Ausführung von P Vorbedingung ϕ gilt
<ϕ> P <ψ>
„ Spezifikation (zur partiellen Korrektheit)
Partielle Korrektheit: Hoare-Kalkül
Bsp: <5 = 5>
x = 5;
<x = 5>
x = 5;
<5 = 5>
<x = 5>
II.1.4. Verifikation - 6 -
x ist Variable, t ist Ausdruck (ohne Seiteneffekte),
ϕ [x/t] ist ϕ mit allen x ersetzt durch t
<ϕ [x/t]> x = t; < ϕ >
Zuweisungsregel
x = 5;
<true>
<5 = 5>
x = 5;
<x = 5>
<true>
x = 5;
II.1.4. Verifikation - 7 -
true ⇒ 5 = 5
α⇒ϕ
<x = 5>
<x = 5>, denn:
<5 = 5> x = 5; <x = 5>
Bsp: <true>
<α> P <ψ>
<ϕ> P <ψ>
Konsequenzregel 1 (Stärkere Vorbedingung)
x = 5;
<true>
<true>
<5 = 5>
x = 5;
<x = 5>
<x ≥ 5>
x = 5;
II.1.4. Verifikation - 8 -
x = 5 ⇒ x ≥ 5
ψ⇒β
<x ≥ 5>
<x ≥ 5>, denn:
<true> x = 5; <x = 5>
Bsp: <true>
<ϕ> P <β>
<ϕ> P <ψ>
Konsequenzregel 2 (Schwächere Nachbedg.)
Bsp: <true>
x = 5;
res = x * x + 6;
<res = 31>
<res = 31>
II.1.4. Verifikation - 9 -
res = x * x + 6;
<x = 5>
<x * x + 6 = 31>
x = 5;
<true>
<5 = 5>
< ψ > Q <β>
<ϕ> P Q <β>
<ϕ> P <ψ>
Sequenzregel
<res = y ∧ ¬ x > y >
⇒ <res = max(x,y)>
denn: <res = y ∧ x > y >
<x = max(x,y)>
res = x;
<res = max(x,y)>
Bsp: <true>
res = y;
if (x > y) res = x;
<res = max(x,y)>
und
ϕ ∧ ¬B ⇒ ψ
II.1.4. Verifikation - 10 -
<res = max(x,y)>
if (x > y) res = x;
<res = y>
res = y;
<true>
<y = y>
<ϕ> if (B) {P} <ψ>
<ϕ ∧ B> P <ψ>
Bedingungsregel 1
<ϕ ∧ ¬ B> Q <ψ>
Bsp: <true>
if (x < 0)
res = -x;
else
res = x;
<res = |x|>
und
II.1.4. Verifikation - 11 -
<res = |x|>
res = x;
< ¬ x < 0>
<x = |x|>
<res = |x|>
res = -x;
denn: <x < 0>
<-x = |x|>
<ϕ> if (B) {P} else {Q} <ψ>
<ϕ ∧ B> P <ψ>
Bedingungsregel 2
¬ i > 1>
<i! * res = n!>
res = res * i;
i = i - 1;
denn: <i! * res = n! ∧ i > 1>
<(i-1)! * (res * i) = n!>
<i! * res = n! ∧
<res = n! >
while (i > 1) {res = res * i; i = i - 1; }
<i = n ∧ res = 1>
<i! * res = n!>
i = n; res = 1;
<true>
<ϕ> while (B) {P} < ϕ ∧ ¬ B >
<ϕ ∧ B> P < ϕ >
Schleifenregel
II.1.4. Verifikation - 12 -
invariante
ϕ ist Schleifen-
< ψ > Q <β>
<ϕ> P <ψ>
<ϕ> P Q <β>
„ Sequenzregel
ψ⇒β
<ϕ> P <ψ>
<ϕ> P <β>
α⇒ϕ
<ϕ> P <ψ>
<α> P <ψ>
„ Konsequenzregeln
<ϕ [x/t]> x = t; < ϕ >
„ Zuweisungsregel
ϕ ∧ ¬B ⇒ ψ
<ϕ ∧ ¬ B> Q <ψ>
II.1.4. Verifikation - 13 -
<ϕ> while (B) {P} < ϕ ∧ ¬ B >
<ϕ ∧ B> P < ϕ >
„ Schleifenregel
<ϕ> if (B) {P} else {Q} <ψ>
<ϕ ∧ B> P <ψ>
<ϕ> if (B) {P} <ψ>
<ϕ ∧ B> P <ψ>
„ Bedingungsregeln
Hoare-Kalkül
und
<V = m ∧ B > P <V < m>
Variante ist i,
⇒i ≥ 0
<i = m-1>
<i < m>
II.1.4. Verifikation - 14 -
res = res * i; i = i - 1;
<i = m ∧ i > 1>
<i-1 = m-1>
denn: i > 1
while (i > 1) {res = res * i; i = i - 1; }
B⇒V≥0
Für jede Schleife while (B) {P} finde einen
int-Ausdruck V (Variante der Schleife), so dass:
Terminierung
Vorbedingung: a ≥ 0
}}
Nachbedingung: res = a + b
System.out.println (a + " + " + b + " = " + res);
while (x > 0) {
x = x - 1;
res = res + 1;
}
//Invariante: x ≥ 0 ∧ x + res = a + b
//Variante: x
x = a;
res = b;
public static void main (String [] args) {
System.out.print ("Gib 2 Zahlen ein: ");
int a = IO.eingabe (), b = IO.eingabe (), x, res;
public class Plus {
Verifikation der Addition
II.1.4. Verifikation - 15 -
Vorbedingung: x ≥ y
}}
Nachbedingung: res = x - y
System.out.println (x + " - " + y + " = " + res);
while (x > z) {
z = z + 1;
res = res + 1;
}
//Invariante: x ≥ z ∧ res = z - y
//Variante: x - z
z = y;
res = 0;
public static void main (String [] args) {
System.out.print ("Gib 2 Zahlen ein: ");
int x = IO.eingabe (), y = IO.eingabe (), z, res;
public class Subtract {
Verifikation der Subtraktion
II.1.4. Verifikation - 16 -
}}
System.out.println (n + " prim: " + istPrim);
II.1.4. Verifikation - 17 -
Nachbedingung: istPrim = true gdw. n ist Primzahl
while (teiler <= wurzel) {
if (n % teiler = = 0) istPrim = false;
teiler = teiler + 1; }
//Invariante: n ≥ 2 ∧ wurzel = sqrt(n) ∧
//
istPrim = keine Zahl i mit 2 ≤ i < teiler teilt n
//Variante: wurzel - teiler
public class Prim {
public static void main (String [] args) {
System.out.print ("Gib Zahl ein: ");
int n = IO.eingabe ();
Vorbedingung: n ≥ 2
int wurzel = (int) Math.sqrt (n),
teiler = 2;
boolean istPrim = true;
Verifikation eines Primzahl-Programms
Herunterladen