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 . . .