Technische Universität München Fakultät für Informatik Dr. M. Schneider, Dr. M. Pizka, Dr. A. Vilbig, Dr. R. Letz, G. Bauer, B. Zhang SS 2003 Lösungsvorschläge zu Blatt 6 23. Mai 2003 Übungen zur Vorlesung Einführung in die Informatik IV Eine primitiv rekursive Funktion besteht entweder aus einer der Grundfunktionen: succ : 0 zero : 1 zero : πni : n succn n 1 zero0 0 zero1 n 0 πni x1 xn xi ; aus Komposition primitiv rekursiver Funktionen durch f : m f Æ g : n hi : m g h1 hn 1in mit f x1 xm gh1 x1 xm hnx1 xm oder aus primitiv rekursiven Funktionen g : k k 2 h: durch das Schema der primitiven Rekursion f x1 xk 0 f x1 xk n 1 gx1 xk hx1 xk n f x1 xk n abgekürzt durch f Aufgabe 23 prg h Primitiv rekursive Funktionen Definitionsschema für einstellige Funktionen: Definitionsschema für zweistellige Funktionen: f 0 g gm f m 0 f succn hn f n f m succn hm n f m n sqO 0 sqsuccn sqn 2 n 1 add sqn add 1 mult 2 n also ist sq prg h mit g zero0, h add [π22 add [one2 mult [two2 π21 ]]], one2 succ zero1 π21 und two2 succ succ zero1 π21 . Æ Æ Æ Æ Æ Æ Æ Æ g hn sqn Lösung 6/ Seite 2 µ-rekursive Funktionen Aufgabe 24 Eine µ-rekursive Definition der partiellen Funktion psqrt, die Quadratwurzeln natürlicher Zahlen berechnet: psqrt hx y µh mit h : 2 partiell gegeben durch: psubx y y (psub sei die partielle Subtraktion.) Behauptung: psqrtx w falls w2 x undefiniert sonst Dabei sei w die ganzzahlige Wurzel von x, d.h. die eindeutig bestimmte natürliche Zahl mit der Eigenschaft w2 x w 12 . Beweis: Zu zeigen ist Im Fall w Im Fall w 2 x ist hx y 0 für y w und hx y 0 für y w. 2 x ist hx y 0 oder hx y undefiniert. Sei w2 x. Dann ist x eine Quadratzahl und es gilt y : y w y w psubx y y 0 psubx y y 0 Sei w2 x w 12 . Dann ist x keine Quadratzahl und es gilt y : yw w y Aufgabe 25 nen psubx y y 0 psubx y y undefiniert, da x w 12 y y Äquivalenz von µ-Rekursion und while-Programmen auf Registermaschi- (a) Gegeben sei die folgende µ-rekursive Funktion zur Berechnung der partiellen Subtraktion zweier natürlicher Zahlen a b µha b wobei die primitiv rekursiv definierte Funktion h : N 3 N definiert ist durch die Gleichung ha b y subb y a suba b y Lösung 6/ Seite 3 (i) Jede primitiv rekursive Funktion lässt sich in ein while-programm umsetzen. Die Zuweisung s0 : hsa sb sy wird in das folgende Registermaschinen-Programm M umgesetzt. s0 : 0; while0 pred0 s1 : 0; while1 pred1 s2 : 0; while2 pred2 sa : 0; whilea preda sb : 0; whileb predb sy : 0; whiley predy s0 s1 sb sb : sb sb sb 0; whileb succ0 ; succ1 ; succb ; predb s0 s1 sy sy : s0 sy s1 sy sy 0; whiley succ0 ; succ1 ; succy ; predy s0 sa sa : s0 sa sa 0; whilea pred0 ; succa ; preda s2 sa sa : sa sa 0; whilea succ2 ; succa ; preda s2 s1 : s2 s1 0; while1 pred2 ; pred1 s0 s2 : s0 s2 0; while2 succ0 ; pred2 sb sb : sb 0; whileb succb ; predb sy sy : sy 0; whiley succy ; predy ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ ¼ (ii) Die µ-Rekursion wird in das folgende Registermaschinen-Programm umgesetzt. sy : 0; whiley predy s0 : hsa sb sy ; M while s0 0 do while0 succy ; M sy : sy 1 s0 : hsa sb sy; od (b) Wir zeigen: Jedes while-Programm auf einer Registermaschine lässt sich in eine µ-rekursive Funktion umsetzen. Wir fassen ein while-Programm auf einer n-Registermaschine auf als eine Funktion n n , die den Registern s s1 sn neue Werte zuordnet. (i) succi , predi und ε sind primitiv rekursiv: succi [πn1 succ πni πnn ] predi [πn1 pred πni πnn ] ε id Æ Æ Æ (ii) Sind M1 und M2 µ-rekursiv, so auch M1 ; M2 : M1 ; M 2 M2 M1 (iii) Ist M µ-rekursiv, so auch whilei M : Wir definieren zunächst eine µ-rekursive Funktion p , so dass ps k den Wert der Register nach k-maliger Ausführung des Programms M liefert. (p ist µ-rekursiv, das M µ-rekursiv ist, d.h. das Ergebnis kann auch undefiniert sein, wenn M nicht terminiert) p : n n ps 0 s ps sucn M ps n Wir setzen: whilei M s ps k Lösung 6/ Seite 4 wobei k die kleinste Zahl ist, so dass nach k-maliger Ausführung des Programms M das Register si den Wert 0 hat, falls diese Zahl existiert, ansonsten undefiniert. k µhs min y πi ps y 0 mit hs y πi ps y Falls das while-Programm terminiert, ist die µ-rekursive Funktion definiert, ansonsten undefiniert. Aufgabe 26 (H) Äquivalenz von primitiver Rekursion und for-Programmen auf Registermaschinen (a) Um die in der Aufgabenstellung gegebene Behauptung zu beweisen, ist zu zeigen: primitiv rekursiv for-berechenbar und primitiv rekursiv for-berechenbar. „“: Der Aufbau primitiv rekursiver Funktionen legt folgendes Induktionsschema nahe: Der Induktionsanfang erstreckt sich über die Grundfunktionen, ein Induktionsschluß ist über die Komposition und das letztgenannte Schema zu führen. Induktionsanfang: Die Grundfunktionen sind for-berechenbar: succ zero πni succ ; f or ε ; f or ε ; 1 1 1 ; f ori 1 ε; f ori1 ε; ; f orn ε; Induktionsschluß: Induktionshypothese ist, dass die primitiv rekursive Funktionen g und h (bzw. hi ) for-berechenbar sind; entsprechende Programme seien im weiteren durch G, H bzw. Hi abgekürzt. Zu zeigen ist dann, dass jede Funktion die aus g und h (bzw. hi ) in einem Schritt, also durch Komposition oder durch das Schema der primitiven Rekursion aufgebaut werden kann, wiederum for-berechenbar ist. Komposition: Funktionen, die durch Komposition aus G und H i berechnet werden, sind ebenfalls for-berechenbar, denn f Æ g h1 hn H ; 1 ; Hn ; G . Schema der primitiven Rekursion: Es bleibt noch der Fall zu betrachten, dass eine Funktion f , die durch das Schema der primitiven Rekursion aus forberechenbaren Funktionen gx1 xk und hx1 xk y z entsteht, wiederum for-berechenbar ist. Durch das folgende Programm wird f berechnet: G; f orm ε; predy fory H succm ; result := gx1 xk ; m := 0; y := y - 1; for i := y to 0 do result := hx1 xk m result ; m := m + 1; od hierbei verifiziert man durch Induktion über die Anzahl der Schleifendurchläufe, dass result nach i 0 Schleifendurchläufen den Wert f x1 xk i Lösung 6/ Seite 5 hat. Die Schleife wird im ganzen y-mal durchlaufen, so dass result schließlich den gesuchten Wert f x1 xk y annimmt. Schließlich muß das angegebene Pseudocode-Programm noch in ein Registermaschinen-Programm transformiert werden: Die beiden dort auftretenden Zuweisungen der Variablen result sind per Induktionsannahme RM-berechenbar; wir kürzen diese mit G und H ab. „ “: Wir zeigen: Jedes for-Programm auf der Registermaschine lässt sich in eine primitive rekursive Funktion umsetzen. (i) succi , predi und ε sind primitiv rekursiv. succi [πn1 succ πni πnn ] predi [πn1 pred πni πnn ] ε id Æ Æ Æ (ii) Sind M1 und M2 primitiv rekursiv, so auch M1 ; M2 : M1 ; M 2 M2 M1 (iii) Ist M primitiv rekursiv, so auch die k-malige Ausführung ps k von M: n p : n ps 0 s ps sucn M ps n Ist M primitiv rekursiv, so auch f or i M : Wir setzen: f ori M s ps i (b) Die in der Aufgabenstellung gegebene For-Schleife unterscheidet sich von einer WhileSchleife im wesentlichen dadurch, dass bei einer For-Schleife die Zahl der Schleifendurchläufe von Anfang an, durch die im Register i gespeicherte Zahl n auf eben dieses n festgelegt ist. Bei einer While-Schleife ist dagegen die Zahl der Durchläüfe nicht fest vorgegeben, sondern hängt von dem Programm M ab. Aus dem eben durchgeführten Beweis können wir also folgern, dass bei primitiver Rekursion die Zahl der rekursiven Aufrufe abschätzbar ist. Darin unterscheiden sich primitiv rekursive Funktionen von µ-rekursiven, wo die Zahl der rekursiven Aufrufe von vornherein nicht feststeht. Aufgabe 27 (P) Rekursionsoperator Teilaufgabe a) Die Fakultätsfunktion f ac ist primitiv rekursiv definiert durch f ac0 f acn 1 succzero0 succ zero0 n 1 f acn mult succn f acn mult succ π21 π22 n f acn Æ Æ Æ Die zuletzt aufgeführte Gleichung erfüllt somit die für das Rekursionsschema erforderliche Form f n 1 hn f n, d.h. der Rekursionsoperator verknüpft die beiden primitv rekursiven Funktionen g h Æ Æ succ zero0 mult succ π21 π22 Æ Lösung 6/ Seite 6 Teilaufgabe b) und c) -- Constant function zero zero0 = 0 -- Successor function succ x = x + 1 -- Dyadic projections pi21 (x, y) = x pi22( x, y) = y -- Composition operators for monadic and dyadic function g comp g h x = g(h x) comp2 g h1 h2 x = g(h1 x, h2 x) -- Auxiliary definition of multiplication mult(x, y) = x * y -- Primitive recursion operator for monadic function f pr :: Int -> ((Int, Int) -> Int) -> (Int -> Int) pr g h = f where f(0) = g f(n+1) = h(n, f(n)) -- Primitive recursive definition of the factorial fac = pr (succ(zero0)) (comp2 mult (comp succ pi21) pi22)