Tutoraufgabe 1 (Typcasting):

Ähnliche Dokumente
Tutoraufgabe 1 (Casting): Programmierung WS17/18 Übungsblatt 2 (Abgabe ) Allgemeine Hinweise:

Tutoraufgabe 1 (Zweierkomplement): Lösung: Programmierung WS16/17 Lösung - Übung 2

Tutoraufgabe 1 (Hoare-Kalkül):

Tutoraufgabe 1 (Verifikation):

Programmierung WS12/13 Lösung - Übung 1 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder

Übung zur Vorlesung Programmierung

1. Erste Schritte 2. Einfache Datentypen 3. Anweisungen und Kontrollstrukturen 4. Verifikation 5. Reihungen (Arrays) II.1.4. Verifikation - 1 -

n 1. Erste Schritte n 2. Einfache Datentypen n 3. Anweisungen und Kontrollstrukturen n 4. Verifikation n 5. Reihungen (Arrays)

! 1. Erste Schritte! 2. Einfache Datentypen! 3. Anweisungen und Kontrollstrukturen! 4. Verifikation! 5. Reihungen (Arrays) II.1.4. Verifikation - 1 -

1. Erste Schritte 2. Einfache Datentypen 3. Anweisungen und Kontrollstrukturen 4. Verifikation 5. Reihungen (Arrays) II.1.4. Verifikation - 1 -

int x = 3; int y = 11; public A () { this.x = z; y *= z;

Institut für Programmierung und Reaktive Systeme. Java 2. Markus Reschke

Programmierung WS14/15 Lösung - Präsenzübung C. Aschermann, F. Frohn, J. Hensel, T. Ströder

Tutoraufgabe 1 (Pilze):

Programmierung WS18/19 Lösung - Präsenzübung

Vorkurs Informatik WiSe 16/17

Java I Vorlesung Imperatives Programmieren

Vorkurs Informatik WiSe 17/18

Programmierung WS12/13 Lösung - Präsenzübung M. Brockschmidt, F. Emmes, C. Otto, T. Ströder

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

Gegeben sind die folgenden Programmausschnitte: I. Programmausschnitt: II. Programmausschnitt: III. Programmausschnitt: IV. Programmausschnitt:

Einführung in die Programmierung

Präsenzübung Programmierung WS 2016/2017

Programmierung WS17/18 Lösung - Präsenzübung 09./

Aufgabe 1 (Programmanalyse):

Programmierpraktikum

Übung Informatik I - Programmierung - Blatt 2

Kapitel 4. Programmierkurs. Datentypen. Arten von Datentypen. Wiederholung Kapitel 4. Birgit Engels, Anna Schulze WS 07/08

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache

Kapitel 4. Programmierkurs. Datentypen. Arten von Datentypen. Datentypen und Operatoren Ganzzahlige Numerische Datentypen Logischer Datentyp

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache. Variablen. Operationen Zuweisung. Variablen

Präsenzübung Programmierung WS 2017/2018

2 Eine einfache Programmiersprache

Korrektheit und Hoare-Kalkül für Imperative Programme

Einstieg in die Informatik mit Java

Abschnitt 11: Korrektheit von imperativen Programmen

Vorname: Nachname: Matrikelnummer: Studiengang (bitte ankreuzen): Informatik Bachelor Informatik Lehramt Mathematik Bachelor Sonstige:

Informatik I Übung, Woche 40

JAVA-Datentypen und deren Wertebereich

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

PK-Einstufungstest. 1. Allgemeine Multiple-Choice-Aufgaben

Ein erstes Java-Programm

Datentypen und Operatoren

Übungen zur Vorlesung Wissenschaftliches Rechnen I

Gedächtnis. Während der Abarbeitung eines Algorithmus müssen sich Dinge gemerkt werden bzw. auf Dingen wird gerechnet. Zugriff.

Wie entwerfe ich ein Programm?

System.out.println("TEXT");

PK-Einstufungstest. 1. Allgemeine Multiple-Choice-Aufgaben. Aufgabe 1.1. Alle Aufgaben beziehen sich auf Java.

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

Einführung in die Programmierung WS 2009/10. Übungsblatt 5: Typen, Variablen und einfache Methoden in Java

Erste Java-Programme (Scopes und Rekursion)

Tutoraufgabe 1 (Verikation mit Arrays):

Ausdrücke und primitive Typen

Programmierung für Mathematik HS11

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

2 Programmieren in Java I noch ohne Nachbearbeitung

Einfache Arrays. Dr. Philipp Wendler. Zentralübung zur Vorlesung Einführung in die Informatik: Programmierung und Softwareentwicklung

PK-Einstufungstest. 1. Allgemeine Multiple-Choice-Aufgaben. Alle Aufgaben beziehen sich auf Java.

Programmierkurs Java

Programmiervorkurs Einführung in Java Tag 1

Informatik I Übung, Woche 40

Übung Informatik I - Programmierung - Blatt 3

Einstieg in die Informatik mit Java

Ein String ist in Java eigentlich eine Klasse, wir können ihn aber zunächst als Datentyp betrachten, der zur Speicherung von Zeichenketten dient.

Funktionen nur wenn dann

Intensivübung zu Algorithmen und Datenstrukturen

GI Vektoren

Übungsblatt 1. Java Vorkurs (WS 2017)

Informatik 1 für Nebenfachstudierende Beispiele für Klausuraufgaben

Programmierstarthilfe SS 2009 Fakultät für Ingenieurwissenschaften und Informatik 4. Blatt Für die Woche vom bis zum 22.5.

Welche Informatik-Kenntnisse bringen Sie mit?

Javakurs für Anfänger

Einstieg in die Informatik mit Java

Tag 3 Repetitorium Informatik (Java)

Schwerpunkte. 8. Ausdrücke, Operatoren (einfache Typen) Beispiel: Schaltjahr Test. Einführendes Beispiel: Grundprobleme

Algorithmen als systematische Vorgehensweisen zur Lösung eines formal definierten Problems

Test-Klausuraufgaben Softwaretechnik Fachbereich BW, für WINFO

Tag 4 Repetitorium Informatik (Java)

Vorbereitende Aufgaben

{P} S {Q} {P} S {Q} {P} S {Q} Inhalt. Hoare-Kalkül. Hoare-Kalkül. Hoare-Tripel. Hoare-Tripel. Hoare-Tripel

3. Java - Sprachkonstrukte I

Algorithmen als systematische Vorgehensweisen zur Lösung eines formal definierten Problems

Algorithmen und ihre Programmierung

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

1 Aufgaben 1.1 Umgebungsvariable setzen: CLASSPATH

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 1 - Variablen und Kontrollstrukturen

Programmieren in Java

CoMa 04. Java II. Paul Boeck. 7. Mai Humboldt Universität zu Berlin Institut für Mathematik. Paul Boeck CoMa 04 7.

Sprachkonstrukte. Einführung in Java. Folie 1 von Mai Ivo Kronenberg

5.3 Auswertung von Ausdrücken

Angewandte Mathematik und Programmierung

Programmiertechnik Übungen zu Klassen & -methoden

Wiederholungsanweisungen II

Transkript:

Prof. aa Dr. J. Giesl Programmierung WS18/19 S. Dollase, M. Hark, D. Korzeniewski Tutoraufgabe 1 (Typcasting: Bestimmen Sie den Typ und das Ergebnis der folgenden Java-Ausdrücke. Begründen Sie Ihre Antwort und geben Sie dabei für alle auftretenden Typkonvertierungen den resultierenden Typ und den resultierenden Wert an. Geben Sie darüber hinaus an, ob es sich um explizite oder implizite Konvertierungen handelt. Sollte der Ausdruck nicht typkorrekt sein, begründen Sie, worin der Fehler besteht. Dabei seien die Variablen x, y und z wie folgt deklariert: var x = 1; var y = 2; var z = 3; a false && true b 10 / 3 c 10 / 3. d x == y? x > y : y < z e (byte (127 + 1 f x + y + z g x + y + "z" h 1 0 i 5 + (2 > 3? 7.2 : 4 1

var x = 1; var y = 2; var z = 3; Die Variablen x, y und z haben alle den Typ int. a false && true Der Ausdruck liefert den Wert false vom Typ boolean, da die logische Und-Verknüpfung zweier boolean Werte hier ganz normal ausgeführt werden kann. b 10 / 3 Der Ausdruck liefert den int-wert 3, da bei der Division zweier int-werte in Java Ganzzahldivision ohne Rest verwendet wird. c 10 / 3. Der Ausdruck liefert den double-wert 3.3333333333333335, da der int-wert 10 für die double-division erst implizit zum double 10.0 konvertiert wird. d x == y? x > y : y < z Der Ausdruck liefert den boolean-wert true, da zuerst der boolean-vergleich x == y zu false und anschließend y < z zu true ausgewertet wird. Der Typ von x > y ist ebenfalls boolean, weshalb kein Fehler auftritt. e (byte (127 + 1 Der Ausdruck liefert das Ergebnis -128 vom Typ byte, da zuerst die int-addition durchgeführt wird und das Ergebnis +128 anschließend explizit in den byte-datentypen konvertiert wird. Dieser Datentyp kann diesen Wert allerdings nicht darstellen. Die sich ergebende Dualzahl 10000000 wird im 8-Bit Zweierkomplement als -128 interpretiert. f x + y + z Durch die Auswertung von links nach rechts wird zuerst x + y ausgewertet. Dafür wird das Zeichen x zuerst implizit in die int-zahl 120 konvertiert. Dies ergibt also 120 + 2 = 122. Dieser Wert wird dann mit der int-zahl 3 addiert, und somit wird der Gesamtausdruck zu 125 vom Typ int ausgewertet. g x + y + "z" Durch die Auswertung von links nach rechts wird zuerst x + y zur int-zahl 3 ausgewertet. Dieser Wert wird dann mit dem String "z" verkettet, und somit wird der Gesamtausdruck zu "3z" vom Typ String ausgewertet. h 1 0 Der Ausdruck liefert einen Fehler, da 1 und 0 vom Typ int sind und damit der boolean-vergleich nicht möglich ist. i 5 + (2 > 3? 7.2 : 4 Zuerst wird der Typ des bedingten Ausdruck inferiert. Da 7.2 den Typ double hat, wird der int 4 implizit in den double 4.0 gecastet, d.h. der bedingte Ausdruck wertet zu einem double aus. Somit wird der int 5 implizit in den double 5.0 gecastet. Bei der Auswertung wird ebenfalls erst der bedingte Ausdruck ausgewertet. Da 2 > 3 zu false auswertet, wird die Gleitkommazahladdition von 5.0 und 4.0 ausgewertet und das Endergebnis ist der double 9.0. Aufgabe 2 (Typcasting: (1.5 + 1 + 1 + 2 + 1 + 1.5 + 1 = 9 Punkte Bestimmen Sie den Typ und das Ergebnis der folgenden Java-Ausdrücke. Begründen Sie Ihre Antwort und geben Sie dabei für alle auftretenden Typkonvertierungen den resultierenden Typ und den resultierenden Wert an. Geben Sie darüber hinaus an, ob es sich um explizite oder implizite Konvertierungen handelt. Sollte der Ausdruck nicht typkorrekt sein, begründen Sie, worin der Fehler besteht. Dabei seien die Variablen x, y und z wie folgt deklariert: var x = 5.; var y = false; var z = 3; 2

a (float (2/(long 3 b x == y && x!= y c x == z && x!= z d a /98 == 3.F/(int4.6 e (x < z + 2.2F f result, wobei result folgende Variablendeklaration hat: int result = x < (byte a? a : b g u, wobei u folgende Variablendeklaration hat: var u = true? 1 : 2.0; var x = 5.; var y = false; var z = 3; x hat den Typ double, y den Typ boolean und z den Typ int. a (float (2/(long 3 Der int Wert 3 wird explizit in den Typ long umgewandelt. Anschließend wird 2 vom Typ int implizit in den Typ long umgewandelt und die Ganzzahldivision des Typs long durchgeführt, welche den long Wert 0 ergibt. Anschließend wird dieser explizit in den float 0.0 gecastet. b x == y && x!= y Die Variable x hat den Typ double, welcher nicht in den Typ boolean gecastet werden kann. Da auch boolean nicht zu double gecastet werden kann, ergibt sich ein Typfehler. c x == z && x!= z Die Variable z wird implizit in den double Wert 3.0 gecastet und mit x verglichen. Es ergibt sich false. Da der zweite Ausdruck korrekt getypt ist, da z implizit in einen double gecastet werden kann, wird der Ausdruck zu false ausgewertet. Java geht von links nach rechts vor und wertet den rechten Ausdruck nicht mehr aus. d a /98 == 3.F/(int4.6 Der char a wird implizit in den int 97 gecastet. Anschließend wird die int Division zu 0 ausgewertet. Auf der rechten Seite wird 4.6 zuerst explizit in den int 4 gecastet und anschließend implizit in den float 4.0. Die float Division ergibt dann 0.75. Anschließend wird das Ergebnis 0 der linken Seite implizit in den float 0.0F gecastet. Der Vergleich ergibt den boolean false. e (x < z + 2.2F Das Ergebnis des Vergleichs ist ein boolean. Da boolean und float nicht ineinander gecastet werden können, ergibt sich ein Typfehler. f result, wobei result folgende Variablendeklaration hat: int result = x < (byte a? a : b Wie eben wird der char a explizit in den byte 97 gecastet und anschließend implizit in den double 97.0. Der Vergleich wertet dann zum boolean true aus, weshalb sich der char a ergibt, der schließlich implizit zum int 97 gecastet wird. g u, wobei u folgende Variablendeklaration hat: var u = true? 1 : 2.0; Da 2.0 den Typ double hat, wird der int 1 implizit in den double 1.0 gecastet. Der bedingte Ausdruck wertet dann zu 1.0 aus, da die Bedingung true ist. Also hat die Variable u den Typ double und den Wert 1.0. 3

Tutoraufgabe 3 (Programmierung: Schreiben Sie ein einfaches Java-Programm, welches den Benutzer auffordert, eine positive ganze Zahl (d. h. größer als 0 einzugeben. Danach soll das Programm eine Zahl einlesen. Diese Eingabeaufforderung mit anschließendem Einlesen soll solange wiederholt werden, bis der Benutzer wirklich eine positive Zahl eingibt. Wenn die Benutzereingabe keine Zahl ist, darf sich das Programm beliebig verhalten. Anschließend soll der Benutzer aufgefordert werden, ein Wort einzugeben. Das Wort soll eingelesen und schließlich so oft hintereinander geschrieben ausgeben werden, wie durch die eingegebene positive Zahl festgelegt wurde. Ein Ablauf des Programms könnte z.b. so aussehen: Bitte geben Sie eine positive Zahl ein 0 Bitte geben Sie eine positive Zahl ein 3 Bitte geben Sie ein Wort ein Programmierung ProgrammierungProgrammierungProgrammierung Hinweise: Verwenden Sie die Klasse SimpleIO zum Einlesen und Ausgeben von Werten. 4

/** * Programm zum Einlesen einer positiven Zahl und eines Worts, welches das Wort * anschliessend so oft ausgibt, wie durch die Zahl festgelegt wurde. */ public class Multiecho { public static void main ( String [] args { // Einlesen der Zahl mit Ueberpruefung, dass die Zahl positiv ist : int zahl = 0; while ( zahl < 1 { zahl = SimpleIO. getint (" Bitte geben Sie eine positive Zahl ein "; // Einlesen des Wortes : String wort = SimpleIO. getstring (" Bitte geben Sie ein Wort ein "; // Ausgabe des Wortes so oft wie durch die Zahl festgelegt wurde : int i = 0; String multi = ""; while (i < zahl { multi += wort ; i ++; SimpleIO. output ( multi, " MultiEcho "; Aufgabe 4 (Programmierung: (9 Punkte Implementieren Sie einen einfachen 8 Bit-Zweierkomplement Konverter in Java. Für die Ein-/Ausgabe soll die bereitgestellte Klasse SimpleIO genutzt werden. Die Benutzung anderer vordefinierten Methoden als der hier explizit genannten ist nicht gestattet. Um einen String str1 in einem Fenster mit dem Titel 1 str2 auszugeben, nutzen Sie SimpleIO.output(str1, str2. Um einen Wert vom Typ type einzulesen, nutzen Sie SimpleIO.getType(str, wobei str der Text ist, der dem Benutzer im Eingabefenster angezeigt wird. Um einen Wert vom Typ int einzulesen, benutzen Sie also z.b. SimpleIO.getInt("Bitte eine ganze Zahl eingeben". Das Programm soll den Benutzer zunächst auswählen lassen, ob von Dezimaldarstellung in Binärdarstellung oder von Binärdarstellung in Dezimaldarstellung konvertiert werden soll. Zur Dezimaldarstellung benutzen wir den primitiven Datentyp int, zur Binärdarstellung den vordefinierten Typ String. Bedenken Sie, dass mit dem 8 Bit Zweierkomplement die ganzen Zahlen { 128... 127 dargestellt werden können und alle Binärdarstellungen genau 8 Einträge haben. Zur Auswahl sollen folgende Schlüsselwörter verwendet werden: Decimal Bei dieser Auswahl soll der Benutzer eine ganze Zahl als Dezimalzahl eingeben. Falls diese nicht im 8 Bit Zweierkomplement dargestellt werden kann, soll die Eingabe wiederholt werden, bis eine darstellbare Zahl eingegeben wird. Anschließend soll die Eingabe mit dem Verfahren aus der Vorlesung ins Zweierkomplement konvertiert und ausgegeben werden. Binary Bei dieser Auswahl soll das Programm den Benutzer nach einer ganzen Zahl im 8 Bit Zweierkomplement fragen, die als String eingelesen wird. Das Einlesen soll wiederholt werden bis ein String der 1 Sie dürfen in dieser Aufgabe immer z.b. Zweierkomplement als Titel verwenden. 5

Länge 8 eingegeben wird. Enthält der String Zeichen, die weder 0 noch 1 sind, soll eine Fehlermeldeung ausgegeben und das Programm beendet werden. Eine korrekte Eingabe soll mit dem Verfahren aus der Vorlesung in eine Dezimalzahl umgewandelt und ausgegeben werden. Gibt der Nutzer weder Decimal noch Binary ein, so soll er erneut gefragt werden. Ein Beispiellauf des Programms könnte also so aussehen: Bitte waehlen Sie aus : Decimal : Dezimalzahl ins Zweierkomplement konvertieren. Binary : 8- Bit - Zweierkomplement als Dezimalzahl darstellen. Programmierung Bitte waehlen Sie aus : Decimal : Dezimalzahl ins Zweierkomplement konvertieren. Binary : 8- Bit - Zweierkomplement als Dezimalzahl darstellen. Decimal Bitte geben Sie eine ganze Zahl zwischen -128 und 127 ein. -13 Ihre Dezimalzahl im Zweierkomplement dargestellt ist 11110011 bzw. Bitte waehlen Sie aus : Decimal : Dezimalzahl ins Zweierkomplement konvertieren. Binary : 8- Bit - Zweierkomplement als Dezimalzahl darstellen. Binary Bitte geben Sie eine ganze Zahl im 8- Bit - Zweierkomplement ein. 11110011 Ihr 8- Bit - Zweierkomplement entspricht der Dezimalzahl -13 Hinweise: Um zwei Strings str1 und str2 auf Gleichheit zu testen, verwenden Sie str1.equals(str2 (und nicht str1 == str2. Für die Berechnung der Länge eines String str rufen Sie str.length( auf. Um den i-ten char eines String str zu bestimmen, rufen Sie str.charat(i auf. Der vorderste Eintrag eines String hat den Index 0. Der letzte Buchstabe hat den Index str.length(-1. Die Benutzung von impliziter Typinferenz durch var x =...; ist nicht gestattet, da diese zu unleserlichem Programmcode führt. Legen Sie die bereitgestellte Datei SimpleIO.java einfach im gleichen Verzeichnis wie ihre Lösung ab. Dann findet javac diese automatisch und kompiliert sie. Ihr Konverter muss die Verfahren aus der Vorlesung verwenden, um die Eingabe zu konvertieren. Ansonsten werden keine Punkte vergeben. /** * Programm zur Konvertierung von kleinen Dezimalzahlen in 8- Bit Binaerdarstellung * und von 8- Bit - Binaerdarstellung in Dezimalzahlen. */ public class Zweierkomplement { public static void main ( String [] args { String mode ; do{ mode = SimpleIO. getstring (" Bitte waehlen Sie aus :\ n" + " Decimal : Dezimalzahl ins Zweierkomplement konvertieren.\ n" + 6

" Binary : 8- Bit - Zweierkomplement als Dezimalzahl darstellen."; while (!( " Decimal ". equals ( mode " Binary ". equals ( mode ; if(" Decimal ". equals ( mode { int inputint ; do{ inputint = SimpleIO. getint ( " Bitte geben Sie eine ganze Zahl zwischen -128 und 127 ein."; while ( inputint < -128 inputint > 127; // Zu negativen Zahlen muss 2^8=256 addiert werden if ( inputint < 0{ inputint = 256+ inputint ; String output = ""; // Berechnet den Bit - String for ( int i = 0; i < 8; i ++{ if( inputint % 2 == 0{ output = " 0" + output ; inputint = inputint /2; else { output = " 1" + output ; inputint = ( inputint -1/2; SimpleIO. output ( " Ihre Dezimalzahl im Zweierkomplement dargestellt ist " + output," Zweierkomplement "; else { String inputstring ; do{ inputstring = SimpleIO. getstring ( " Bitte geben Sie eine ganze Zahl im 8- Bit - Zweierkomplement ein."; while ( inputstring == null inputstring. length (!= 8; int result = 0; // Die Zweierpotenzen werden " on the run " berechnet int power = 1; // Wird true, wenn es kein Bit - String ist. boolean error = false ; // Durchlaeuft den String und berechnet die Dezimahlzahl for ( int pos = 7; pos >=0 &&! error ; pos --{ char curr = inputstring. charat ( pos ; if( curr == 1 { // Das vorderste Bit symbolisiert -2^8 result += ( pos == 0? (- power : power ; // Kein Bit - String -> Fehlermeldung und Schleifenabbruch else if ( curr!= 0 { SimpleIO. output (" Das ist kein Bit String "," Zweierkomplement "; error = true ; power *= 2; // Ausgabe nur bei Fehlerfreiheit 7

if (! error { SimpleIO. output (" Ihr 8- Bit - Zweierkomplement entspricht der Dezimalzahl " + result," Zweierkomplement "; Tutoraufgabe 5 (Verifikation: Gegeben sei folgendes Java-Programm über den Integer-Variablen x, y, z und r: 0 x 0 < y (Vorbedingung z = 0; r = x; while (r >= y { r = r - y; z = z + 1; z = x div y (Nachbedingung Vervollständigen Sie die folgende Verifikation der partiellen Korrektheit des Algorithmus im Hoare-Kalkül, indem Sie die unterstrichenen Teile ergänzen. Hierbei dürfen zwei Zusicherungen nur dann direkt untereinander stehen, wenn die untere aus der oberen folgt. Hinter einer Programmanweisung darf nur eine Zusicherung stehen, wenn dies aus einer Regel des Hoare-Kalküls folgt. Hinweise: div steht für die Integer-Division, d.h. 5 div 3 ergibt z.b. 1. Sie dürfen beliebig viele Zusicherungs-Zeilen ergänzen oder streichen. In der Musterlösung werden allerdings genau die angegebenen Zusicherungen benutzt. Bedenken Sie, dass die Regeln des Kalküls syntaktisch sind, weshalb Sie semantische Änderungen (beispielsweise von x + 1 = y + 1 zu x = y nur unter Zuhilfenahme der Konsequenzregeln vornehmen dürfen. Es empfiehlt sich oft, bei der Erstellung der Zusicherungen in der Schleife von unten (d. h. von der Nachbedingung aus vorzugehen. z = 0; r = x; while (r >= y { r = r - y; 0 x 0 < y 0 = 0 x = x 0 x 0 < y z = 0 x = x 0 x 0 < y z = 0 r = x 0 x 0 < y x div y = z + r div y 0 r 0 < y x div y = z + r div y 0 r 0 < y r y x div y = z + 1 + (r y div y 0 r y 0 < y x div y = z + 1 + r div y 0 r 0 < y 8

z = z + 1; x div y = z + r div y 0 r 0 < y x div y = z + r div y 0 r 0 < y r y z = x div y Aufgabe 6 (Verifikation: Gegeben sei folgendes Java-Programm über den Integer-Variablen x, res und c: x 0 (Vorbedingung res = -x; c = x; while (c > 0 { res = res + 2 * c; c = c - 1; res = x x (Nachbedingung (7 Punkte Vervollständigen Sie die folgende Verifikation der partiellen Korrektheit des Algorithmus im Hoare-Kalkül, indem Sie die unterstrichenen Teile ergänzen. Hierbei dürfen zwei Zusicherungen nur dann direkt untereinander stehen, wenn die untere aus der oberen folgt. Hinter einer Programmanweisung darf nur eine Zusicherung stehen, wenn dies aus einer Regel des Hoare-Kalküls folgt. Hinweise: Sie können die Gauß sche Summenformel benutzen: Für eine natürliche Zahl x gilt 0 + 1 + + x = x k=0 k = x (x+1 2. Somit ist also x 2 = 2 x k x. Die leere Summe (bei der der Startindex größer als der Zielindex ist wird als 0 interpretiert. Beispielsweise gilt also k = x 0. k=x+1 Sie dürfen beliebig viele Zusicherungs-Zeilen ergänzen oder streichen. In der Musterlösung werden allerdings genau die angegebenen Zusicherungen benutzt. Bedenken Sie, dass die Regeln des Kalküls syntaktisch sind, weshalb Sie semantische Änderungen (beispielsweise von x + 1 = y + 1 zu x = y nur unter Zuhilfenahme der Konsequenzregeln vornehmen dürfen. Es empfiehlt sich oft, bei der Erstellung der Zusicherungen in der Schleife von unten (d. h. von der Nachbedingung aus vorzugehen. k=0 res = -x; c = x; x 0 x 0 x = x x = x x 0 res = x x = x x 0 ( res = x c = x x res = 2 k x c 0 k=c+1 9

while (c > 0 { ( x res = k=c+1 res + 2 c = res = res + 2 * c; ( res = c = c - 1; x k=c 1+1 2 k ( x k=c 1+1 x c 0 c > 0 2 k x c 1 0 2 k x c 1 0 ( x res = 2 k x c 0 k=c+1 ( x res = 2 k x c 0 c > 0 k=c+1 res = x x Um von der vierten auf die fünfte Zusicherung zu kommen benutzen wir die Konsequenzregel, denn die leere Summe, bei der also der Startindex echt größer als der Zielindex ist, wird als 0 interpretiert, d.h. ( x 2 k x = x. k=x+1 Um von der vorletzten auf die letzte Zusicherung zu kommen, benutzen wir ebenfalls die Konsequenzregel, denn nach der Gauß schen Summenformel gilt ( x ( x x (x + 1 2 k x = 2 k x = 2 x = x x + x x = x x. 2 k=1 k=0 Tutoraufgabe 7 (Verifikation: Gegeben sei folgendes Java-Programm, das zu zwei Eingaben x = a und y = b den Wert a b berechnet. x = a y = b (Vorbedingung res = 0; while (x!= y { if (x > y { x = x - 1; else { y = y - 1; res = res + 1; res = a b (Nachbedingung a Vervollständigen Sie die folgende Verifikation des Algorithmus im Hoare-Kalkül, indem Sie die unterstrichenen Teile ergänzen. Hierbei dürfen zwei Zusicherungen nur dann direkt untereinander stehen, wenn die untere aus der oberen folgt. Hinter einer Programmanweisung darf nur eine Zusicherung stehen, wenn dies aus einer Regel des Hoare-Kalküls folgt. Hinweise: 10

Für alle x, y Z gilt: und x > y = (x 1 y = x y 1 x y (x > y = x (y 1 = x y 1. Achtung: Falls lediglich x y bzw. x y gilt, gelten beide Gleichungen nicht im Allgemeinen. Sie dürfen beliebig viele Zusicherungs-Zeilen ergänzen oder streichen. In der Musterlösung werden allerdings genau die angegebenen Zusicherungen benutzt. Bedenken Sie, dass die Regeln des Kalküls syntaktisch sind, weshalb Sie semantische Änderungen (beispielsweise von x+1 = y+1 zu x = y nur unter Zuhilfenahme der Konsequenzregeln vornehmen dürfen. Klammern dürfen und müssen Sie jedoch eventuell bei der Anwendung der Zuweisungsregel setzen. Es empfiehlt sich oft, bei der Erstellung der Zusicherungen in der Schleife von unten (d. h. von der Nachbedingung aus vorzugehen. b Beweisen Sie die Terminierung des Algorithmus im Hoare-Kalkül. a x = a y = b x = a y = b 0 = 0 res = 0; x = a y = b res = 0 res = a b x y while (x!= y { res = a b x y x y res + 1 = a b ( x y 1 x y if (x > y { res + 1 = a b ( x y 1 x y x > y res + 1 = a b (x 1 y x = x - 1; res + 1 = a b x y else { res + 1 = a b ( x y 1 x y (x > y res + 1 = a b x (y 1 y = y - 1; res + 1 = a b x y res + 1 = a b x y res = res + 1; res = a b x y res = a b x y x = y res = a b b Eine gültige Variante für die Terminierung ist V = x y. Die Schleifenbedingung B = x y impliziert x y > 0 und damit V 0. Es gilt: if (x > y { x y = m x y x y 1 < m x y x y 1 < m x y x > y (x 1 y < m 11

x = x - 1; else { y = y - 1; res = res + 1; x y < m x y 1 < m x y (x > y x (y 1 < m x y < m x y < m x y < m Damit ist die Terminierung der einzigen Schleife des Programms gezeigt. Aufgabe 8 (Verifikation: Gegeben sei folgendes Java-Programm über den Integer-Variablen a, b, x, res und y: b 0 (Vorbedingung x = b; res = a; y = 1; while (x > 0 { if (x % 2 == 0 { y = 2 * y; x = x / 2; else { res= res + y; y = 2 * y; x = (x - 1 / 2; res = a + b (Nachbedingung (9 + 3 = 12 Punkte a Vervollständigen Sie die folgende Verifikation des Algorithmus im Hoare-Kalkül, indem Sie die unterstrichenen Teile ergänzen. Hierbei dürfen zwei Zusicherungen nur dann direkt untereinander stehen, wenn die untere aus der oberen folgt. Hinter einer Programmanweisung darf nur eine Zusicherung stehen, wenn dies aus einer Regel des Hoare-Kalküls folgt. Hinweise: Die Programmanweisung x / 2 berechnet das abgerundete Ergebnis der Ganzzahldivision, d.h. x 2. Sie dürfen beliebig viele Zusicherungs-Zeilen ergänzen oder streichen. In der Musterlösung werden allerdings genau die angegebenen Zusicherungen benutzt. Bedenken Sie, dass die Regeln des Kalküls syntaktisch sind, weshalb Sie semantische Änderungen (beispielsweise von x+1 = y+1 zu x = y nur unter Zuhilfenahme der Konsequenzregeln vornehmen dürfen. Es empfiehlt sich oft, bei der Erstellung der Zusicherungen in der Schleife von unten (d. h. von der Nachbedingung aus vorzugehen. res = a + b 12

b Untersuchen Sie den Algorithmus P auf seine Terminierung. Für einen Beweis der Terminierung muss eine Variante angegeben werden und mit Hilfe des Hoare-Kalküls die Terminierung bewiesen werden. a b 0 b 0 b = b a = a 1 = 1 x = b; x 0 x = b a = a 1 = 1 res = a; x 0 x = b res = a 1 = 1 y = 1; x 0 x = b res = a y = 1 a + b = res + x y x 0 while (x > 0 { a + b = res + x y x 0 x > 0 if (x % 2 == 0 { a + b = res + x y x 0 x > 0 x mod 2 = 0 a + b = res + x 2 2 y x 2 0 y = 2 * y x = x / 2 else { res = res + y y = 2 * y x = (x - 1 / 2; a + b = res + x 2 y x 2 0 a + b = res + x y x 0 a + b = res + x y x 0 x > 0 (x mod 2 = 0 a + b = res + y + x 1 2 2 y x 1 2 0 a + b = res + x 1 2 a + b = res + x 1 2 2 y x 1 2 a + b = res + x y x 0 a + b = res + x y x 0 0 y x 1 2 0 a + b = res + x y x 0 x > 0 res = a + b b Wir wählen als Variante V = x. Hiermit lässt sich die Terminierung des Programms beweisen, denn für die einzige Schleife im Programm (mit Schleifenbedingung B = x > 0 gilt: B V 0, denn B = x > 0 V > 0 und die folgende Ableitung ist korrekt: x = m x > 1 if (x % 2 == 0 { x = m x > 1 x mod 2 = 0 x 2 < m y = 2 * y x = x / 2 else { x 2 < m x < m x = m x > 1 (x mod 2 = 0 x 1 2 < m 13

res = res + y y = 2 * y x = (x - 1 / 2; x 1 2 < m x 1 2 < m x < m x < m Aufgabe 9 (Deck 1: (Codescape Lösen Sie die Räume von Deck 1 des Spiels Codescape. Ihre Lösung für Räume dieses Codescape Decks wird nur dann für die Zulassung gezählt, wenn Sie die Lösung bis Mittwoch, den 31.10.2018 um 08:00 abschicken. 14