Prof. Dr. A. Poetzsch-Heffter Dipl.-Inform. J. O. Blech Dipl.-Inform. M. J. Gawkowski Dipl.-Inform. N. Rauch
TU Kaiserslautern
Fachbereich Informatik AG Softwaretechnik
Lösungvorschlag zum Übungsblatt 7: Software-Entwicklung I (WS 2007/08)
Aufgabe 1 Funktionen höherer Ordnung
1 (* Teilaufgabe a *)
2 (* foldl :: (’a * ’b -> ’b) -> ’b -> ’a list -> ’b *)
3 fun foldl f e [] = e
4 | foldl f e (x::xs) = foldl f (f(e,x)) xs
5 6
7 (* Teilaufgabe b, c, d *)
8 (* Anwendungen von foldr *)
9 val int_list_sum = foldr (op+) 0
10 val real_list_sum = foldr Real.+ 0.0
11 val string_list_concatenation = foldr (op^) ""
12 (***
13 val int_list_sum = fn : int list -> int
14 val real_list_sum = fn : real list -> real
15 val string_list_concatenation = fn : string list -> string
16 val it = () : unit
17 ***)
18
19 (* Teilaufgabe e *)
20 datatype ’a btree = Leaf of ’a | Branches of ’a * ’a btree * ’a btree
21
22 fun isomorph_trees f (eq : ’a * ’a -> bool) (Leaf a) (Leaf b) = eq(f a,b)
23 | isomorph_trees f eq (Branches(a,t1,t2)) (Branches(b,t1’,t2’)) =
24 (eq(f a,b)) andalso (isomorph_trees f eq t1 t1’) andalso (isomorph_trees f eq t2 t2’)
25 | isomorph_trees f eq _ _ = false
26
27 (***
28 val isomorph_trees = fn
29 : (’a -> ’b) -> (’b * ’b -> bool) -> ’a btree -> ’b btree -> bool
30 ***)
31
Aufgabe 2 Terminierung
a)
fun tuples [] = []
| tuples (x::[]) = [(x,0,0)]
| tuples (x::y::[]) = [(x,y,0)]
| tuples (x::y::z::xs) = (x,y,z)::(tuples xs)
• Die MengeP der zulässigen Parameter umfasst alle Werte des Typsint list.
• Wähle(N,≤)als noethersche Ordnung.
• Alsδ wähle die Funktionlength: int list → int, die eine List lals Argument entgegennimmt und die Länge vonlberechnet.
• Zu zeigen:
i) xsist zulässiger Parameter in dem Funktionsaufruf(tuplesxs): ok.√ ii)
δ(xs) = lengthxs
< length(z ::xs)
< length(y ::z ::xs)
< length(x ::y ::z ::xs)
= δ(x ::y ::z ::xs)
ok.√ b)
datatype decoration = Tinsel of int | Light of int datatype xmasstree = Leaf of decoration
| Branches of decoration * xmasstree * xmasstree
(* 1. Muster *)
fun switchoff (Leaf(Tinsel i)) = Leaf(Tinsel i) (* 2. Muster *)
| switchoff (Leaf(Light 0)) = Leaf(Light 0) (* 3. Muster *)
| switchoff (Leaf(Light n)) = switchoff (Leaf(Light (n-1))) (* 4. Muster *)
| switchoff (Branches(Tinsel i, t1, t2)) =
(Branches(Tinsel i,switchoff t1,switchoff t2)) (* 5. Muster *)
| switchoff (Branches(Light 0, t1, t2)) =
(Branches(Light 0,switchoff t1,switchoff t2)) (* 6. Muster *)
| switchoff (Branches(Light n, t1, t2)) = switchoff(Branches(Light (n-1),t1,t2))
• Die MengeP der zulässigen Parameter umfasst alle Werte des Typsxmasstree.
• Wähle(N,≤)als noethersche Ordnung.
• Sei nodes : xmasstree →int eine Funktion, welche die Summe aller Knoten in einem Baum berechnet, undlights :xmasstree →int eine Funktion, welche die Summe aller Wertenin den Knoten Light n berechnet. Dann wähle als δ die Funktion sum : xmasstree →int, die einen Baumtals Eingabe entgegennimmt undnodes(t) +lightsberechnet.
• Zu zeigen:
i) Zulässigkeit der Parameter in rekursiven Aufrufen:
3. Muster: Da Leaf(Light n) vom Typ xmasstree ist, istLeaf(Light(n−1)) im rekur- siven Aufrufswitchoff (Leaf(Light (n−1)))ist auch vom Typ xmasstree und damit zulässig.√
4. Muster: Da Branches(Tinsel i,t1,t2) vom Typ xmasstree ist, sind t1 und t2 sind auch beide vom Typ xmasstree und damit zulässige Parameter im rekursiven Aufruf Branches(Tinsel i,switchoff t1,switchoff t2).√
5. Muster: DaBranches(Light 0,t1,t2)vom Typxmasstree ist, sind aucht1 undt2vom Typxmasstree und damit zulässige Parameter in rekursiven Aufrufenswitchoff t1 und switchoff t2.√
6. Muster: Da Branches(Light n,t1,t2) vom Typ xmasstree ist, sind auch t1 und t2 vom Typ xmasstree und damit zulässige Parameter im rekursiven Aufruf switchoff(Branches(Light(n−1),t1,t2).√
ii) 3. Muster
δ(Leaf(Light(n−1))) = nodes(Light(n−1)) +lights(Lights(n−1))
= 1 +n−1
< 1 +n
= nodes(Light n) +lights(Lights n)
= δ(Leaf(Light n)) √ 4. Muster
δ(t1) = nodes(t1) +lights(t1)
< 1 +nodes(t1) +nodes(t2) + 0 +lights(t1) +lights(t2)
= nodes(Branches(T insel i, t1, t2)) +lights(Branches(T insel i, t1, t2))
= δ(Branches(T insel i, t1, t2)) δ(t2) = nodes(t2) +lights(t2)
< 1 +nodes(t1) +nodes(t2) + 0 +lights(t1) +lights(t2)
= nodes(Branches(T insel i, t1, t2)) +lights(Branches(T insel i, t1, t2))
= δ(Branches(T insel i, t1, t2)) √ 5. Muster (Beweise analog wie im vierten Muster)
δ(t1) < δ(Branches(Light0, t1, t2))
δ(t2) < δ(Branches(Ligth0, t1, t2)) √ 6. Muster
δ(Branches(Light(n−1), t1, t2))
= nodes(Branches(Light(n−1), t1, t2) +lights(Branches(Light(n−1), t1, t2)
= 1 +nodes(t1) +nodes(t2) + (n−1) +lights(t1) +lights(t2)
< 1 +nodes(t1) +nodes(t2) +n+lights(t1) +lights(t2)
= nodes(Branches(Light n, t1, t2)) +lights(Branches(Light n, t1, t2))
= δ(Branches(Light n, t1, t2)) √
Aufgabe 3 Induktionsbeweise
a) Übliche Definition von rev.
Beweis:
rev (a @ b) = rev b @ rev a:
Induktion über a I.V.
a =[]:
rev (a @ b) =
rev ([] @ b) = rev b = rev b @ [] = rev b @ rev [] = rev b @ rev a I.S.
a = xs -> a = x::xs
rev (xs @ b) = rev b @ rev xs ->
rev (x#xs @ b)= rev b @ rev x#xs:
rev (x#xs @ b) = rev (xs @ b) @ [x] =IV rev b @ rev xs @ [x] = rev b @ rev x#xs.
b) f (0) = 0
f (n) = n*2-1 + f (n-1)
geschlossene Form : f(n) = n^2 I.V
n = 0
f(0) = 0 = 0^2 I.S.
n -> n+1 f(n) = n^2:
f(n+1) = (n+1)*2-1 + f(n) =IV (n+1)*2-1 + n^2 = 2*n+2 -1 + n^2 = n^2 + 2*n + 1 = (n + 1)^2
c) f (1) = LEAF
f (n) = NODE f(n-1) f(n-1)
geschlossene Form : f(n) erzeugt 2^n-1 Knoten I.V
n = 0
f(1) = LEAF
f(1) erzeugt einen Knoten = 2^1-1 Knoten = ein Knoten I.S.
n -> n+1
f(n) = erzeugt 2^n-1 Knoten:
f(n+1) = NODE f(n) f(n) also
f(n+1) erzeugt 1+(f(n) erzeugte Knoten) + (f(n) erzeugte Knoten) =IV 1+ 2^n-1+2^n-1 Knoten = 2*(2^n)-1 erzeugte Knoten =
2^(n+1) - 1 erzeugte Knoten