Wolfgang Hönig / Andreas Ecke / Maik Globisch / Mathias Hinkel SS 10 inoffizielle Probeklausur Programmierung“ ” 06./07. August 2010 Studiengang: Dipl.-Informatik, Erg.studium Softwaretechnik, Informationssystemtechnik, Dipl.-Medieninformatik, Dipl.-Mathematik 1. Aufgabe (Strukturelle Induktion): (6 Punkte) Folgende Definitionen seien gegeben: 1 2 3 4 5 6 7 8 9 10 11 data Tree t = N i l t | Node t t | Branch ( Tree t ) ( Tree t ) sumTree sumTree sumTree sumTree : : Tree ( Nil t ) ( Node a ( Branch Int −> Int = t b) = a + b l r ) = ( sumTree l ) + ( sumTree r ) mergeTree : : Tree mergeTree ( N i l a ) mergeTree ( Node a mergeTree ( Branch mergeTree b d ) Int −> Tree Int −> Tree Int ( N i l b ) = Node a b b ) ( Node c d ) = Branch ( N i l ( a+c ) ) ( N i l ( b+d ) ) a b ) ( Branch c d ) = Branch ( mergeTree a c ) ( Zeigen Sie unter Verwendung der oben aufgeführten Definition mit Hilfe der strukturellen Induktion die Gültigkeit der Gleichung sumTree (mergeTree b b)= 2∗(sumTree b) für jedes b :: Tree Int. Geben Sie bei den Umformungen die jeweils benutzen Gesetzmäßigkeiten / Definitionen an. 2. Aufgabe (Haskell-Programmierung): (3 + 3 + 2 = 8 Punkte) (a) Geben Sie eine für die Speicherung von AVL-Bäumen geeignete Datenstruktur an. Benutzen Sie diese dann auch zur Lösung der Aufgabenteile (b) und (c). (b) Schreiben Sie in Haskell eine Funktion balance einschließlich Typdefinition, die an jedem Knoten eines beliebigen AVL-Baums des Typs aus (a) in das Knotenmerkmal für die Balance den Balancewert einträgt. Geben Sie einen Aufruf ihrer Funktion an! (c) Schreiben Sie in Haskell eine Funktion liste, die eine absteigend geordnete Liste der Schlüsselwerte, die in dem AVL-Baum (des Typs aus (a)) auftreten, erzeugt. Geben Sie außerdem die notwendigen weiteren Deklarationen sowie einen Aufruf ihrer Funktion an. Hinweis: Falls Sie sonst Hilfsfunktionen benötigen, müssen Sie diese vollständig angeben! Hinweis: Ein AVL-Baum ist ein binärer Suchbaum, der zusätzlich einen Balancewert besitzt. Dieser Wert berechnet sich aus der längsten Pfadlänge des rechten Teilbaums Minus der längsten Pfadlänge des linken Teilbaums. 3. Aufgabe (Operationelle Semantik von C1 ): (2 + 2 + 2 + 2 = 8 Punkte) (a) Übersetzen Sie nachfolgende C1 -Statements in entsprechenden AM1 -Kode mit baumstrukturierten Adressen. Zwischenschritte brauchen Sie keine anzugeben. Die zugehörige Symboltabelle ist: tabf +lDecl = [g/(proc, 1), f/(proc,2), a/(var,global,1), b/(var,lokal,1), c/(var,lokal,-3), x(var-ref,-2)]. 1 2 s c a n f ( ”%i ” , x ) ; i f ( ∗ x > b∗ a ) g ( ∗ x , &c , x ) ; (b) Folgendes AM1 -Programm P rog sei gegeben: 1 2 3 4 5 6 7 8 INIT 1 ; CALL 1 3 ; JMP 0 ; INIT 0 ; LOAD( g l o b a l , 1 ) ; RET 1 ; INIT 1 ; READI( −2) ; 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 LIT 1 ; ADD; STOREI( −3) ; RET 2 ; INIT 2 ; READ( g l o b a l , 1 ) ; LIT −2; PUSH; CALL 4 ; LOADA( g l o b a l , 1 ) ; PUSH; LOADA( l o k a l , 1 ) ; PUSH; CALL 7 ; WRITE( g l o b a l , 1 ) ; RET 0 ; Lassen Sie dieses auf der AM1 ablaufen und berechnen Sie die Programmsemantik. Die AM1 befindet sich bereits im Zustand σ = (17, , 5 : 3 : 0 : 0 : 0 : −2, 3, 8, ). Dokumentieren Sie den Zustand der AM1 nach Ausführung jedes Befehls. (c) Stellen Sie - wie in den Übungen praktiziert - den Aufbau des Laufzeitkellers für den Zustand σ graphisch dar. Markieren Sie dabei insbesondere die Aktivierungsblöcke sowie den Referenzzeiger REF. (d) Geben Sie alle Funktionsköpfe, der in Teilaufgabe (b) enthaltenen Funktionen in C1 -Notation an. Treffen Sie gegebenfalls sinnvolle Annahmen. Ist der gegebenen AM1 -Kode vollständig in C1 umwandelbar? 4. Aufgabe (Unifikation): 5 Punkte Es seien δ ein vierstelliges, σ ein zweistelliges, γ ein einstelliges und α ein nullstelliges Funktionssymbol. V = {x1 , x2 , x3 , x4 } sei eine Menge von Variablen. Wenden Sie den Unifikationsalgorithmus auf die Terme t1 und t2 an und ermitteln Sie deren allgemeinsten Unifikator: t1 = δ(γ(x4 ), γ(γ(α)), γ(x4 ), σ(γ(x2 ), x1 )) t2 = δ(γ(x4 ), γ(x3 ), γ(σ(x1 , α)), σ(γ(γ(x4 )), γ(γ(x2 )))) 5. Aufgabe (Axiomatische Semantik): (3 + 3 = 6 Punkte) Für die Verifikationsformel {(n ≥ 0) ∧ (k = n) ∧ (z = 0)} while (k>0) {z=z+k; k=k-1;} {(z = n(n+1) )} wurden die ersten (korrekten) Regelanwendungen des Beweisbaumes aufgeschrieben (siehe 2 unten). Dabei sind die Ausdrücke A bis E noch unbekannt. Es gelten: SV = stärkere Vorbedingung, SN = schwächere Nachbedingung, IR = Iterationsregel, CR = Compoundregel, SR = Sequenzregel. {D} z=z+k; {E} {E} k=k-1; {C} (SR) {D} z=z+k; k=k-1; {C} (CR) {D} {z=z+k; k=k-1;} {C} (IR) {A} while (k>0) {z=z+k; k=k-1;} {B} B ⇒ (z = n(n+1) ) 2 (SN) ((n ≥ 0) ∧ (k = n) ∧ (z = 0)) ⇒ A {A} while (k>0) {z=z+k; k=k-1;} {(z = (SV) {(n ≥ 0) ∧ (k = n) ∧ (z = 0)} while (k>0) {z=z+k; k=k-1;} {(z = n(n+1) )} 2 n(n+1) )} 2 (a) Geben Sie die Schleifeninvariante an. (b) Geben Sie die Ausdrücke für A, B, C, D, E an. Kürzen Sie gegebenenfalls die Schleifeninvariante mit SI ab. 6. Aufgabe (λ-Kalkül): (2 + 2 + 3 = 7 Punkte) (a) Gegeben sei folgender λ-Term: (λxz.(λx.(λz.z)xy)(λy.z))(y(λx.y)) Reduzieren Sie diesen Term bis seine Normalform erreicht ist. Schreiben Sie – bevor Sie einen Ableitungsschritt ausführen – für die relevanten (Teil-)Ausdrücke die Mengen der freien bzw. der gebundenen Vorkommen von Variablen auf. (b) Eine Funktion f : N+ × N+ → N+ , x > y sei wie folgt definiert: f (x, y) = 3y f (x, y) = 3f (xy − 1, y − 1) + (x − y) x teilbar durch 2 sonst Geben Sie zur Funktion f den zugehörigen λ-Term < F > an, so dass < f >=< Y >< F > gilt. (c) Gegeben sei: < G >= (λgx. < ite > (< iszero > x) < 1 > (< mult > x(g(< pred > x)))) Berechnen Sie schrittweise < Y >< G >< 2 >. Führen Sie im Rechenprozess zweckmäßige Abkürzungen der λ-Terme ein. Welche mathematische Funktion berechnet der λ-Term < G >? Bei der Lösung dieser Aufgabe dürfen Sie die λ-Terme < succ >, < pred >, < iszero >, < true >, < f alse >, < ite >, < add >, < sub >, < mult >, < mod > und < n > mit n ∈ IN als bekannt voraussetzen. Des Weiteren dürfen Sie bei der Lösung die folgenden Beziehungen benutzen: < succ >< n >=⇒∗ < n + 1 > < pred >< n >=⇒∗ < n − 1 > für n > 0 < add >< n1 >< n2 >=⇒∗ < n1 + n2 > < sub >< n1 >< n2 >=⇒∗ < n1 − n2 > für n1 ≥ n2 < mult >< n1 >< n2 >=⇒∗ < n1 · n2 > < mod >< n >< m >=⇒∗ < z > wobei 0 ≤ z < m mit z = n − i · m, i ∈ N s1 wenn s =⇒∗ < true > ∗ < ite > s s1 s2 =⇒ s2 sonst < true > wenn s =⇒∗ < 0 > < iszero > s =⇒∗ < f alse > sonst < Y >= (λh.((λy.h (y y)) (λy.h (y y))))