Beweise von Programmeigenschaften

Werbung
Beweis von Programmeigenschaften
Beweis von Programmeigenschaften
Gliederung
Algorithmen und Datenstrukturen – Einführung
Beweise von Programmeigenschaften
1
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
Beweis von Programmeigenschaften
Einleitung
Beispiele
c
Winter 2008/09, 8. Dezember 2008, 2008/09
D.Rösner
D. Rösner
Beweis von Programmeigenschaften
AuD 2008/2009 . . .
Einleitung
Beispiele
Beweis von Programmeigenschaften
Wie kann man sich über Eigenschaften von Programmen
Klarheit verschaffen?
ein Weg sind formale Beweise
funktionale Sprachen wie Haskell sind hierfür besonders
geeignet
die definierenden Gleichungen können beim
Schlussfolgern über Programme genutzt werden
D. Rösner
AuD 2008/2009 . . .
D. Rösner
Beweis von Programmeigenschaften
AuD 2008/2009 . . .
Einleitung
Beispiele
Beweis von Programmeigenschaften
wir betrachten meist universelle, d.h. allquantifizierte
Aussagen über Eigenschaften von Programmen
Beispiel:
für alle endlichen Listen xs gilt:
rev (rev xs) == xs
wichtige Unterscheidung:
um solche allquantifizierten Aussagen zu widerlegen, reicht
ein Gegenbeispiel
um solche allquantifizierten Aussagen zu belegen,
benötigen wir einen Beweis
D. Rösner
AuD 2008/2009 . . .
Beweis von Programmeigenschaften
Einleitung
Beispiele
Beweis von Programmeigenschaften
Beweis von Programmeigenschaften
Prinzip der strukturellen Induktion für Listen:
Beachte: Beispiele können Beweise nicht ersetzen
Beispiel einer (unzutreffenden) Behauptung:
für alle endlichen Listen xs gilt:
rev xs == xs
für manche Listen trifft die Behauptung zwar zu:
rev [] == []
rev [1] == [1]
rev [x] == [x]
-- x beliebig
rev [x,x] = [x,x]
-- x beliebig
rev [x,y,x] = [x,y,x] -- x,y beliebig
...
die Behauptung gilt aber nicht für alle endlichen Listen xs
ein Gegenbeispiel reicht aus, z.B.:
rev [1,2] == [2,1] /= [1,2]
D. Rösner
Beweis von Programmeigenschaften
um zu beweisen, dass eine logische Eigenschaft P(xs)
für alle endlichen Listen xs gilt, sind zwei Dinge zu tun
Induktionsanfang oder -basis:
Beweise P([]) direkt
Induktionsschritt:
Beweise P(x:xs) unter der Annahme, dass P(xs) gilt
m.a.W.: es ist zu zeigen, dass
P(xs) ⇒ P(x:xs)
dabei: P(xs) . . . Induktionshypothese oder
Induktionsannahme
s.a. [Tho99]
D. Rösner
AuD 2008/2009 . . .
Einleitung
Beispiele
Beweis von Programmeigenschaften
Beispiel für Beweis einer Programmeigenschaft
Gegeben seien die folgenden Definitionen:
AuD 2008/2009 . . .
Einleitung
Beispiele
Beweis einer Programmeigenschaft cont.
Struktur des Beweises:
sum :: [Int] -> Int
sum []
= 0
sum (x:xs) = x + sum xs
(sum.1)
(sum.2)
doubleAll :: [Int] -> [Int]
doubleAll []
= []
doubleAll (z:zs) = 2*z : doubleAll zs
(doubleAll.1)
(doubleAll.2)
Behauptung:
für alle endlichen Listen xs ganzer Zahlen gilt:
Einleitung
Beispiele
Induktionsbasis:
Beweise, dass
sum (doubleAll []) = 2 * sum[]
-- (base)
Induktionsschritt:
Beweise, dass
sum (doubleAll (x:xs)) = 2 * sum (x:xs) --(ind)
unter der Induktionshypothese
sum (doubleAll xs) = 2 * sum xs
--(hyp)
sum (doubleAll xs) = 2*sum xs
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Beweis von Programmeigenschaften
Einleitung
Beispiele
Beweis von Programmeigenschaften
Beweis einer Programmeigenschaft cont.
Einleitung
Beispiele
Beweis einer Programmeigenschaft cont.
Induktionsschritt:
Induktionsbasis:
Linke Seite:
sum(doubleAll []) = sum []
= 0
... (doubleAll.1)
... (sum.1)
Rechte Seite:
2*sum [] = 2 * 0 = 0
Damit:
Induktionsbasis bestätigt
... (sum.1)
sum (doubleAll (x:xs))
= sum (2*x : doubleAll xs)
= 2*x + sum(doubleAll xs)
= 2*x + 2*sum xs
= 2*(x + sum xs)
= 2* sum (x:xs)
...
...
...
...
...
(doubleAll.2)
(sum.2)
(hyp)
Arithmetik
(sum.2)
q.e.d.
c
2008/09
DR
D. Rösner
Beweis von Programmeigenschaften
AuD 2008/2009 . . .
D. Rösner
Einleitung
Beispiele
Beweis von Programmeigenschaften
weitere Beispiele für Induktionsbeweise
AuD 2008/2009 . . .
Einleitung
Beispiele
weitere Induktionsbeweise cont.
Struktur des Beweises:
Behauptung:
Induktionsbasis:
Beweise, dass
length (xs ++ ys)
=
length xs + length ys
length ([] ++ ys) = length [] + length ys --(base)
Dabei gelten die folgenden Definitionen:
length []
length (z:zs)
= 0
= 1 + length zs
Induktionsschritt:
Beweise, dass
(length.1)
(length.2)
length ((x:xs) ++ ys) = length (x:xs) + length ys --(ind)
unter der Induktionshypothese
[]
++ zs = zs
(w:ws) ++ zs = w : (ws ++ zs)
D. Rösner
AuD 2008/2009 . . .
(++.1)
(++.2)
length (xs ++ ys) = length xs + length ys --(hyp)
D. Rösner
AuD 2008/2009 . . .
Beweis von Programmeigenschaften
Einleitung
Beispiele
Beweis von Programmeigenschaften
weitere Induktionsbeweise cont.
weitere Induktionsbeweise cont.
Sei reverse definiert durch:
reverse []
= []
reverse (z:zs) = reverse zs ++ [z]
Einleitung
Beispiele
Struktur des Beweises für Beziehung (reverse++):
Induktionsbasis: Beweise, dass
....................................................
Induktionsschritt: Beweise, dass
....................................................
unter der Induktionshypothese
....................................................
(reverse.1)
(reverse.2)
Behauptung:
für alle endlichen Listen xs und ys gilt (reverse++), d.h.
reverse (xs ++ ys) = reverse ys ++ reverse xs
D. Rösner
Beweis von Programmeigenschaften
D. Rösner
AuD 2008/2009 . . .
Einleitung
Beispiele
Ausführung des Beweises
Beweis von Programmeigenschaften
AuD 2008/2009 . . .
Einleitung
Beispiele
Literatur:
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Herunterladen