Invariante und Algorithmenentwurf Timm Grams Hochschule Fulda Fachbereich Elektrotechnik und Informationstechnik © Timm Grams, Fulda, 07.09.02 (6.5.07)
Einführung Was dem Naturwissenschaftler die Naturgesetze, das sind dem Informatiker die Invarianten. Die Invariante erfasst den wesentlichen Kern eines Algorithmus, sie ist sein „Gesetz“. Die Invariante ist Grundlage des Algorithmenent- wurfs. Bei einem Algorithmus ist konsequent zu unterscheiden zwischen der Handlungsanweisung und der Invarianten. Die Handlungsanweisung erfasst den dynamischen, die Invariante den statischen Aspekt eines Algorithmus.
Beispiel: Zahlenwandlung Wandlung der Dezimalzahl 202 in die Darstellung zur Basis 5 Stufe k Relation 0 202 = 20250 1 202 = 4051 + 250 2 202 = 852 + 051 + 250 3 202 = 153 + 352 + 051 + 250
Zahlenwandlung - Operatoren Die Zahlenwandlung basiert auf der ganzzahligen Division mit Rest Die dafür nötigen Operatoren in C sind / und % / ist der Divisionsoperator % ist der Modulo-Operator zur Bestimmung des Rests Beispiele: 202/5 = 40 und 202%5 = 2 Fundamentale Formel der ganzzahligen Arithmetik: z = (z/b) ·b + z %b
Invariante und Endebedingung Die Invariante ist eine Aussage, die vor Eintritt in den Rechenschritt eines Algorithmus erfüllt ist, und die nach dem Schritt erneut wahr ist. Der Algorithmus endet, wenn die Endebedingung erfüllt ist
Grundstruktur von Algorithmen in C while(B)S B S A I A Initialisierungs-Anweisungen B Schleifenbedingung. Für B 0 wird S ausgeführt, für B = 0 (Endebedingung) nicht S Schleifenanweisung (meist eine Verbundanweisung) I Invariante I (B =0) I (B 0) I
Beispiel: Wandlung der Zahl Z in Darstellung zur Basis B I (z 0) I (z =0) I z r[k++]= z%b; z= z/b; k=0; k=0; while(z){ r[k++]=z%b; z=z/b; } Invariante: b = B Z = zbk+r[k-1]bk-1+...+r[1]b1+r[0]b0 0 ≤ r[i ] < B für i < k
Programmbeweis mit der symbolischen Methode 1 Kursive Großbuchstaben bezeichnen mathematische Variable. Programmfragmente werden in Anführungszeichen geschrieben. Anfangs sei z=Z und durchweg gilt b=B. Zu zeigen ist zuerst, dass die Initialisierung „k=0;“ die Invariante wahr macht. Jedenfalls gilt nach der Initialisierung z=Z und k=0. Also: Z = z = zb0 = zbk + r[k-1]bk-1+...+r[1]b1+r[0]b0
Programmbeweis mit der symbolischen Methode 2 Im zweite Schritt ist zu zeigen, dass die Anweisungsfolge „r[k++]=z%b; z=z/b;“ die Invariante erhält: Vor der Anweisungsfolge ist k=K und z=A. Die Invariante wird zu Z = AbK+r[K-1]bK-1+...+r[1]b1+r[0]b0 Nach der Anweisungsfolge ist r[K]=A%b, k=K+1 und z=A/b (ganzzahliger Quotient). Wegen A=(A/b)b+A%b gilt Z = ((A/b)b+A%b)bK+r[K-1]bK-1+...+r[1]b1+r[0]b0 = zbK+1 +r[K]bK+r[K-1]bK-1+...+r[1]b1+r[0]b0 = zbk + r[k-1]bk-1+...+r[1]b1+r[0]b0
Programmbeweis mit der symbolischen Methode 3 Im dritten und letzten Schritt ist zu zeigen, dass aus der Bedingung I (z=0) das gewünschte Resultat folgt. In der Invarianten Z = zbk + r[k-1]bk-1+...+r[1]b1+r[0]b0 ist z=0 zu setzen. Damit ergibt sich Z = r[k-1]bk-1+...+r[1]b1+r[0]b0 Das Array r enthält die Zahlendarstellung der Zahl Z zur Basis B.
Problem Für Z = 0 ist die Summe r[k-1]bk-1+...+r[1]b1+r[0]b0 leer. Das ist auch richtig so: Eine leere Summe hat konventionsgemäß den Wert null. Aber das Wandlungsprogramm kann mit einer leeren Summe nichts anfangen. Was ist zu tun?