• Keine Ergebnisse gefunden

252-0027 Einführung in die Programmierung 11.0 Systematisches Programmierung

N/A
N/A
Protected

Academic year: 2022

Aktie "252-0027 Einführung in die Programmierung 11.0 Systematisches Programmierung"

Copied!
45
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

252-0027

Einführung in die Programmierung

11.0 Systematisches Programmierung

Thomas R. Gross

Department Informatik

(2)

Uebersicht

§ 11.1 Einführung

§ 11.2 Aussagen

§ 11.3 Preconditions und Postconditions

§ 11.4 Hoare Tripel

2

(3)

Methoden von List

add(value) appends value at end of list

add(index, value) inserts given value at given index, shifting subsequent values right

clear() removes all elements of the list

indexOf(value) returns first index where given value is found in list (-1 if not found)

get(index) returns the value at given index

remove(index) removes/returns value at given index, shifting subsequent values left

set(index, value) replaces value at given index with given value size() returns the number of elements in list

§ Was fehlt in dieser Zusammenfassung?

(4)

a) Einige Methoden fehlen ….

b) Information über Laufzeitkosten

c) Information über Annahmen und Anforderungen (wann kann eine Methode verwendet werden, was sind legale

Parameterwerte)

4

(5)

Verantwortlichkeiten

§ Sehen wir uns nochmal die Methode gcd an:

/**

* Calculates the greatest common divisor

* using Euclid's algorithm.

** Returns The greatest common divisor of x and y

*/int gcd(int x, int y) { int r = x % y;

while (r != 0) { x = y;

y = r;

r = x % y;

}

(6)

6

(7)
(8)

int gcd(int x, int y) { int r = x % y;

while (r != 0) { x = y;

y = r;

r = x % y;

} return y;

}

§ Was für Annahmen macht diese Methode?

§ Liefert sie immer das gewünschte Ergebnis?

§ Was für Fälle sollten wir untersuchen?

§ Schreiben Sie die Fälle auf, die Sie für "interessant" halten

§ Simulieren Sie die Ausführung

9

(9)

Verantwortlichkeiten

§ Diese Implementation des ggT erwartet

§ x ≥ 0

§ y > 0

§ Wer ist dafür "verantwortlich"?

§ Klient?

§ Die Methode?

(10)

Klient

/**

* Creates a new Rational with the value x / y.

*/

public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

} 11

(11)

Verantwortlichkeiten

§ (Teil)Lösung hier

gcd(Math.abs(x), Math.abs(y));

§ Kommentar wäre nicht verfehlt

§ gcd kann davon ausgehen dass x ≥ 0

§ "x ≥ 0" ist eine Aussage die hier immer gilt

§ Nicht gelöst ist dass y ≠ 0 sein muss

§ Beispiel soll nicht überladen werden

(12)

(Logische) Aussagen

§ Aussage ("assertion"): Eine Behauptung die entweder wahr oder falsch ist.

§ Wir fragen dann oft "Ist die Aussage wahr"?

§ Beispiele:

§ x ≥ 0 (hängt von x ab)

§ Zürich ist ein Kanton der Schweiz

§ Maseru ist die Hauptstadt Lesothos

§ 11 ist eine Primzahl

§ 120 ist kleiner als 11

§ x geteilt durch 2 ergibt 8 (hängt von x ab) 13

(13)

(Logische) Aussagen

§ Nicht alle Aussagen sind wahr

§ Für einige Aussagen können wir vielleicht nicht sofort entscheiden ob sie wahr oder falsch sind

§ Wichtig ist dass es Sinn macht zu fragen, ob die Aussage wahr oder falsch ist

§ Logisch heisst hier: im Sinne der klassischen Logik

(14)

Arbeiten mit Aussagen

§ Nehmen wir dieses Code Beispiel

if (x > 3) {

// Point A } else {x--;

// Point B x++;// Point C }// Point D

§ Was können wir über den Wert von x an den 4 Stellen sagen?

§ Ist x > 3? Immer? Manchmal? Nie?

15

(15)
(16)

Aussagen und Programme

§ Wir können Aussagen über das Programm machen und fragen ob sie an bestimmten Stellen wahr sind.

§ Gültige Antworten sind IMMER, NIE, oder MANCHMAL.

System.out.print("Type a nonnegative number: ");

double number = console.nextDouble();

// Point A: is number < 0.0 here?

while (number < 0.0) {

// Point B: is number < 0.0 here?

System.out.print("Negative; try again: ");

number = console.nextDouble();

// Point C: is number < 0.0 here?

}

// Point D: is number < 0.0 here?

(MANCHMAL) (IMMER)

(MANCHMAL) (NIE)

(17)

Mit Aussagen arbeiten …

§ Direkt nachdem eine Variable initialisiert wurde, ist ihr Wert bekannt: int x = 3;

// is x > 0? IMMER

§ Ueber die Werte von Parametern wissen wir i.A. nichts:

public static void mystery(int a, int b) { // is a == 10? MANCHMAL

§ Innerhalb eines if, while, usw. wissen wir evtl. etwas:

public static void mystery(int a, int b) { if (a < 0) {

// is a == 10? NIE

(18)

Aussagen und Schleifen

§ Zu Beginn des Rumpfes einer Schleife muss der Test true , ergeben haben:

while (y < 10) {

// is y < 10? IMMER ...

}

§ Direkt nach einer Schleife muss der Test false sein:

while (y < 10) { ...

}

// is y < 10? NIE

(19)

Aussagen und Schleifen

§ Im Rumpf einer Schleife kann der Test false ergeben:

while (y < 10) { y++;

// is y < 10? MANCHMAL }

(20)

"Manchmal"

§ Verschiedene Aktivitäten können dazu führen, dass der Wert einer Variable unbekannt ist (diese führen dann zu

"MANCHMAL" Antworten):

§ Eingabe von Scanner lesen

§ Lesen einer Zahl von einem Random Objekt

§ Uebergabe eines Parameters

§ Wenn für eine Stelle im Programm sowohl die Antwort ”ja"

also auch "nein" möglich ist, dann ist die richtige Antwort

"manchmal".

§ Wenn man sich nicht sicher ist dann ist "Manchmal" eine gute Vermutung

(21)

Beispiel 1

public static void mystery(int x, int y) { int z = 0;

// Point A

while (x >= y) { // Point B x = x - y;

z++;

if (x != y) { // Point C z = z * 2;

}

// Point D }

x < y x == y z == 0 Point A

Point B Point C Point D Point E

MANCHMAL MANCHMAL IMMER NIE MANCHMAL MANCHMAL

MANCHMAL NIE NIE

MANCHMAL MANCHMAL NIE

IMMER NIE MANCHMAL

Welche Aussagen sind an diesen Stellen wahr?

Möglich sind IMMER, NIE oder MANCHMAL.

(22)

26

(23)

Beispiel 2

public static int mystery(Scanner console) { int prev = 0;

int count = 0;

int next = console.nextInt();

// Point A

while (next != 0) { // Point B

if (next == prev) { // Point C

count++;

}

prev = next;

next = console.nextInt();

// Point D }

next == 0 prev == 0 next == prev Point A

Point B Point C Point D Point E

MANCHMAL IMMER MANCHMAL

NIE MANCHMAL MANCHMAL

NIE NIE IMMER

MANCHMAL NIE MANCHMAL

IMMER MANCHMAL MANCHMAL

Welche Aussagen sind an diesen Stellen wahr?

Möglich sind IMMER, NIE oder MANCHMAL.

(24)

Beispiel 3

// Assumes y >= 0, and returns x^y public static int pow(int x, int y) {

int prod = 1;

// Point A

while (y > 0) { // Point B

if (y % 2 == 0) { // Point C x = x * x;

y = y / 2;

// Point D } else {

// Point E

prod = prod * x;

y--;

// Point F } }

// Point G return prod;

}

y > 0 y % 2 == 0 Point A

Point B Point C Point D Point E Point F Point G

Welche Aussagen sind an diesen Stellen wahr?

Möglich sind IMMER, NIE oder MANCHMAL.

y > 0 y % 2 == 0 Point A MANCHMAL MANCHMAL

Point B IMMER MANCHMAL

Point C IMMER IMMER

Point D IMMER MANCHMAL

Point E IMMER NIE

Point F MANCHMAL IMMER

Point G NIE IMMER

(25)

Uebersicht

§ 11.1 Einführung

§ 11.2 Aussagen

§ 11.3 Preconditions und Postconditions

§ 11.4 Hoare Tripel

(26)

Ziel: Aussagen über ein Programm herleiten

§ Welche Aussagen gelten (an einer Stelle) im Programm?

§ Ggf. was für Annahmen sind nötig, dass die Aussage wahr ist

§ Warum?

§ Finden "interessanter" Fälle für Test

§ Erstellen der Bedingungen, die Klienten erfüllen müssen

§ Behandeln von Sonderfällen in einer Methode

§ Wenn die Liste am Anfang leer ist, dann muss das 1. Element auf diese Weise eingefügt werden.

31

(27)

Hoare Logik

§ Tony Hoare entwickelte in den (19)70gern einen Ansatz wie man über Programme logische Schlüsse ziehen kann.

§ Am Anfang betrachten wir nur Zuweisungen, If-Statements, Schleifen und Variable

§ Fürs erste keine Objekte und Methoden

§ Schritt 1: Vorwärts und rückwärts schliessen

§ Schritt 2: Genauere Definition von Aussagen, Vor- und

Nachbedingungen

(28)

Warum

§ Ziel ist es, dass Sie für ein einfaches Programm genau argumentieren können.

§ In der täglichen Programmentwicklung genügt es oft, weniger detailliert zu argumentieren als es die Hoare Logik erforderlich macht.

§ Für einfache Programme ist dieser Ansatz zu aufwändig.

§ Für realistische Progamme wird der Ansatz schnell kompliziert.

§ Wir haben immer noch kein gutes Modell für Objekte und Parallelismus. Aliasing ist eine Herausforderung.

§ Aber manchmal hilft der Ansatz (siehe Fencepost Probleme) 33

(29)

§ Aber eine gute Schulung, systematisch zu programmieren

§ Wir können über Zustände (der Ausführung) eines Programms (und später auch eines Objekts) schlussfolgern

§ Wir können den Effekt eines Programms beschreiben

§ Wir können definieren was es heisst dass eine Aussage “weaker”

(schwächer) oder “stronger” (stärker) ist.

§ Wichtig für die Definition von Schnittstellen (zwischen Modulen)

wenn wir entscheiden müssen welche Bedingungen erfüllt sein

(30)

Beispiel

§ Wie finden wir Aussagen für Stellen im Programm

§ Uns interessieren nicht irgendwelche Aussagen sondern solche, die das Verhalten der Ausführung beschreiben

35

(31)

Beispiel

§ Vorwärts schliessen

§ Vom Zustand vor der Ausführung eines Programm(segments)

§ Nehmen wir an wir wissen (oder vermuten) w > 0 // w > 0

x = 17;

//

y = 42;

//

z = w + x + y;

(32)

Beispiel

§ Vorwärts schliessen

§ Vom Zustand vor der Ausführung eines Programm(segments)

§ Nehmen wir an wir wissen (oder vermuten) w > 0 // w > 0

x = 17;

// w > 0 x == 17 y = 42;

// w > 0 x == 17 y == 42 z = w + x + y;

// w > 0 x == 17 y == 42 z > 59

§ Jetzt wissen wir einiges mehr über das Programm, u.a.

z > 5937

(33)

Beispiel

§ Rückwärts schliessen:

§ Nehmen wir an wir wollen dass z nach Ausführung negativ ist //

x = 17;

//

y = 42;

//

z = w + x + y;

(34)

Beispiel

§ Rückwärts schliessen:

§ Nehmen wir an wir wollen dass z nach Ausführung negativ ist // w + 17 + 42 < 0

x = 17;

// w + x + 42 < 0 y = 42;

// w + x + y < 0 z = w + x + y;

// z < 0

§ Dann müssen wir wissen (oder vermuten) dass vor der Ausführung gilt: w < -59

§ Notwendig und hinreichend 39

(35)

Vorwärts vs Rückwärts, Teil 1

§ Vorwärts schliessen:

§ Bestimmt was sich aus den ursprünglichen Annahmen herleiten lässt.

§ Sehr praktisch wenn eine Invariante gelten soll

§ Rückwärts schliessen:

§ Bestimmt hinreichende Bedingungen die ein gegebenes Ergebnis garantieren

§ Wenn das Ergebniss erwünscht ist, dann folgt aus den Bedingungen die Korrektheit.

§ Ist das Ergebniss unerwünscht, dann reichen die Bedingungen um

(36)

Vorwärts vs Rückwärts, Teil 2

§ Vorwärts schliessen:

§ Simuliert die Ausführung des Programms (für viele “Inputs”

“gleichzeitig”)

§ Oft leicht zu verstehen, erscheint “natürlich”

§ Aber führt dazu dass (viele) Details festgehalten werden, die letztlich irrelevant sind.

41

(37)

Vorwärts vs Rückwärts, Teil 3

§ Rückwärts schliessen:

§ Oft von grossem praktischen Nutzen: Sie müssen verstehen (oder festhalten) was jede Anweisung zum Erreichen eines bestimmten Zustandes beiträgt.

§ Ein Programm(segment) ”rückwärts” zu lesen erfordert Uebung aber führt zu einer neuen Sicht auf ein Programm.

(38)

If-Statement Muster

// initial assumptions if(…) {

// also know test evaluated to true } else {

// also know test evaluated to false }

// either branch could have executed

43

(39)

Terminologie

§ Die Annahme (Aussage), die vor der Ausführung eines Programmsegments gilt, ist die Precondition.

§ Die Aussage, die nach der Ausführung gilt (unter der

Annahme dass die Aussage davor gültig ist), ist die

Postcondition.

(40)

Grundidee(n)

1. Die Precondition für den then-part und den else-part (eines if- Statements) beinhaltet das Ergebnis des Tests.

2. Die Postcondition nach dem if-Statement ist die Disjunktion (“oder”) der Postconditions des then- und else-parts.

45

(41)

Beispiel (Vorwärts)

Nehmen wir an x >= 0 // x >= 0

z = 0;

// x >= 0 ∧ z == 0 if (x != 0) {

// x >= 0 ∧ z == 0 ∧ x != 0 (also x > 0) z = x;

// … ∧ z > 0 } else {

// x >= 0 ∧ z == 0 ∧ !(x != 0) (also x == 0) z = x + 1;

// … ∧ z == 1 }

(42)

Die übliche Notation

§ Statt die Pre/Postconditions in Kommentaren (nach //) schreiben verwenden wir {…}

§ Kein Java mehr …

§ Aber diese Schreibweise hat sich eingebürgert, lange vor Java { w < -59 }

x = 17;

{ w + x < -42 }

47

(43)
(44)

51

(45)

Mehr Terminologie

§ Eine Aussage gilt für den Zustand eines Programms wenn die Auswertung der Aussage mit dem Zustand das Ergebnis true ergibt.

§ Die Auswertung jedes Variable ergibt den Wert der Variable im augenblicklichen Programmzustand.

§ Eine Aussage beschreibt eine Menge von Programmzuständen – genau die, für die die Aussage gilt.

Referenzen

ÄHNLICHE DOKUMENTE

§ Programm: Folge von Anweisungen, die von einem Computer ausgeführt werden (können).. § Programm realisiert

Beachten Sie, dass dafür die Klasse, welche Sie für die Elemente der Kollektion verwenden, das Interface Comparable&lt;T&gt; (T sollte die Klasse selber sein), und damit auch

set( index , value ) replaces value at given index with given value size() returns the number of elements in list.. toString() returns a string representation of the list such as

§ Eine Aussage gilt für den Zustand eines Programms wenn die Auswertung der Aussage (des Ausdrucks) mit dem Zustand das Ergebnis true ergibt. § Die Auswertung jedes Variable ergibt

§ Wenn eine Methode einen Parameter erwartet dann muss dieser auch übergeben werden. printPunkte(); // ERROR: parameter value

containsAll( coll ) returns true if this set contains every element from given set equals( set ) returns true if given other set contains the same elements iterator() returns

§ Invariante und der Schleifen Test (wenn er wahr ist) müssen stark genug sein um zu zeigen dass die Postcondition des Rumpfs auch die Invariante impliziert.. § Invariante und

Ansonsten, falls eine position kleiner als 0 oder grösser als die Länge des Zielliste übergeben wird, soll eine RuntimeException mit der Nachricht “index out of bounds: