Kapitel 4: Programmiermethodik

Werbung
Kapitel 4: Programmiermethodik
Programmieren in Haskell
1
Spezifikation
sort [8, 3, 5, 3, 6, 1]
⇒
[1, 3, 3, 5, 6, 8]
sort "hello world"
⇒
" dehllloorw"
sort ["Bein", "Anfall", "Anna"]
⇒
["Anfall", "Anna", "Bein"]
sort [(1, 7), (1, 3), (2, 2)]
⇒
[(1, 3), (1, 7), (2, 2)]
Programmieren in Haskell
2
sort :: (Ord a) => [a] -> OrdList a
Programmieren in Haskell
3
sort :: (Ord a) => [a] -> OrdList a
ordered
ordered
ordered
ordered
:: (Ord a)
[]
[a]
(a1:a2:as)
Programmieren in Haskell
=> [a] -> Bool
= True
= True
= a1 <= a2 && ordered (a2:as)
3
sort :: (Ord a) => [a] -> OrdList a
ordered
ordered
ordered
ordered
:: (Ord a)
[]
[a]
(a1:a2:as)
=> [a] -> Bool
= True
= True
= a1 <= a2 && ordered (a2:as)
Spezifikation 1: Für alle Listen x :: [τ ] muß gelten:
ordered (sort x)
Programmieren in Haskell
=
True .
(1)
3
sort :: (Ord a) => [a] -> OrdList a
ordered
ordered
ordered
ordered
:: (Ord a)
[]
[a]
(a1:a2:as)
=> [a] -> Bool
= True
= True
= a1 <= a2 && ordered (a2:as)
Spezifikation 1: Für alle Listen x :: [τ ] muß gelten:
ordered (sort x)
=
True .
(1)
Reicht das?
Programmieren in Haskell
3
sort :: (Ord a) => [a] -> OrdList a
ordered
ordered
ordered
ordered
:: (Ord a)
[]
[a]
(a1:a2:as)
=> [a] -> Bool
= True
= True
= a1 <= a2 && ordered (a2:as)
Spezifikation 1: Für alle Listen x :: [τ ] muß gelten:
ordered (sort x)
=
True .
(1)
Reicht das? Nein: \x -> []
Programmieren in Haskell
3
Multimengen
∅ die leere Multimenge,
*a+ die einelementige Multimenge, die genau ein Vorkommen von a enthält,
x ] y die Vereinigung der Elemente von x und y; das „+“ im Vereinigungszeichen
deutet an, daß sich die Vorkommen in x und y akkumulieren.
Programmieren in Haskell
∅]x
=
x
(2)
x]∅
=
x
(3)
x]y
=
y]x
(4)
(x ] y) ] z
=
x ] (y ] z)
(5)
4
bag :: [a] -> Bag a
bag []
= ∅
bag (a:as) = *a+ ] bag as
Spezifikation 2: Für alle Listen x :: [τ ] muß gelten:
ordered (sort x) = True ∧ bag (sort x) = bag x .
Programmieren in Haskell
(6)
5
Strukturelle Rekursion auf Listen
translate :: [Codon] -> Protein
translate []
= []
translate (triplet:triplets)
| aminoAcid == Stp = []
| otherwise
= aminoAcid:translate triplets
where aminoAcid = genCode triplet
length :: [a] -> Int
length []
= 0
length (a:as) = 1 + length as
Programmieren in Haskell
-- vordefiniert
6
Rekursionsbasis: []
Rekursionsschritt: (a:as)
Schema der strukturellen Rekursion auf Listen:
f
f []
f (a : as)
where s
Programmieren in Haskell
::
=
=
=
[σ] -> τ
e1
e2
f as
7
Sortieren durch Einfügen
insertionSort
insertionSort []
insertionSort (a : as)
where s
Programmieren in Haskell
::
=
=
=
(Ord a) => [a] -> OrdList a
e1
e2
insertionSort as
8
Sortieren durch Einfügen
insertionSort
insertionSort []
insertionSort (a : as)
where s
::
=
=
=
(Ord a) => [a] -> OrdList a
e1
e2
insertionSort as
insertionSort :: (Ord a) => [a] -> OrdList a
insertionSort []
= []
insertionSort (a:as) = insert a (insertionSort as)
Programmieren in Haskell
8
Erweitertes Rekursionsschema:
g
g i []
g i (a : as)
where s
insert
insert a []
insert a (a’ : as)
where s
Programmieren in Haskell
::
=
=
=
::
=
=
=
σ1 -> [σ2 ] -> τ
e1
e2
g e3 as
(Ord a) => a -> OrdList a -> OrdList a
e1
e2
insert e3 as
9
insert a []
insert a (a’ : as)
| a <= a’
| otherwise
where s
=
[]
=
=
=
e21
e22
insert e3 as
insert :: (Ord a) => a -> [a] -> [a]
insert a []
= [a]
insert a (a’:as)
| a <= a’
= a:a’:as
| otherwise = a’:insert a as
Programmieren in Haskell
10
isort (8 : 3 : 5 : 3 : 6 : 1 : [])
⇒
ins 8 (isort (3 : 5 : 3 : 6 : 1 : []))
(Def. isort)
⇒
ins 8 (ins 3 (isort (5 : 3 : 6 : 1 : [])))
(Def. isort)
⇒
...
⇒
ins 8 (ins 3 (ins 5 (ins 3 (ins 6 (ins 1 [])))))
⇒
ins 8 (ins 3 (ins 5 (ins 3 (ins 6 (1 : [])))))
(Def. ins)
⇒
ins 8 (ins 3 (ins 5 (ins 3 (1 : ins 6 []))))
(Def. ins)
⇒
ins 8 (ins 3 (ins 5 (1 : ins 3 (ins 6 []))))
(Def. ins)
⇒
...
⇒
1 : ins 8 (ins 3 (ins 5 (ins 3 (ins 6 []))))
Programmieren in Haskell
(Def. isort)
(Def. ins)
11
Strukturelle Rekursion auf Bäumen
data Tree a = Nil
| Leaf a
| Br (Tree a) (Tree a)
deriving Show
Rekursionsbasis (Nil) Das Problem wird für den leeren Baum gelöst.
Rekursionsbasis (Leaf a) Das Problem wird für das Blatt Leaf a gelöst.
Rekursionsschritt (Br l r) Um das Problem für den Baum Br l r zu lösen,
werden rekursiv Lösungen für l und r bestimmt, die zu einer Lösung für
Br l r erweitert werden.
Programmieren in Haskell
12
Schema der strukturellen Rekursion of Bäumen:
f
f Nil
f (Leaf a)
f (Br l r)
where sl
sr
Programmieren in Haskell
::
=
=
=
=
=
Tree σ -> τ
e1
e2
e3
f l
f r
13
size
size
size
size
:: Tree a -> Integer
Nil
= 1
(Leaf _) = 1
(Br l r) = size l + size r
depth
depth
depth
depth
:: Tree a -> Integer
Nil
= 0
(Leaf _) = 0
(Br l r) = max (depth l) (depth r) + 1
Programmieren in Haskell
14
Das allgemeine Rekursionsschema
data T a1 . . . am
=
C1 t11 . . . t1n1
|
...
|
Cr tr1 . . . trnr
Seien li1 ,. . . , lipi mit 1 6 li1 < li2 < · · · < lipi 6 ni die Positionen, an denen der
Konstruktor Ci rekursiv ist
Programmieren in Haskell
15
Allgemeines Schema der strukturellen Rekursion:
f
f (C1 x11 . . . x1n1 )
where s11
...
s1p1
...
f (Cr xr1 . . . xrnr )
where sr1
...
srpr
Programmieren in Haskell
::
=
=
T σ1 . . . σm -> τ
e1
f x1l11
=
f x1l1p1
=
=
er
f xrlr1
=
f xrlrpr
16
Verstärkung der Rekursion
reverse’’ :: [a] -> [a]
-- vordefiniert
reverse’’ []
= []
reverse’’ (a:as) = reverse’’ as ++ [a]
Programmieren in Haskell
17
Verstärkung der Rekursion
reverse’’ :: [a] -> [a]
-- vordefiniert
reverse’’ []
= []
reverse’’ (a:as) = reverse’’ as ++ [a]
Spezifikation:
reel
reel x y
Programmieren in Haskell
::
=
[a] -> [a] -> [a]
reverse x ++ y
17
Rekursionsbasis (x = []):
reel [] y
Programmieren in Haskell
=
reverse [] ++ y
(Spezifikation)
=
[] ++ y
(Def. reverse)
=
y
(Def. (++))
18
Rekursionsschritt (x = a:as):
reel (a:as) y
Programmieren in Haskell
=
reverse (a:as) ++ y
(Spezifikation)
=
(reverse as ++ [a]) ++ y
(Def. reverse)
=
reverse as ++ ([a] ++ y)
(Ass. (++))
=
reverse as ++ (a:y)
(Def. (++))
=
reel as (a:y)
(Spezifikation)
19
reel :: [a] -> [a] -> [a]
reel []
y = y
reel (a:as) y = reel as (a:y)
Programmieren in Haskell
20
reel :: [a] -> [a] -> [a]
reel []
y = y
reel (a:as) y = reel as (a:y)
reverse’’’ :: [a] -> [a]
reverse’’’ as = reel as []
Programmieren in Haskell
20
Strukturelle Induktion auf Listen
Induktionsbasis ([]): Wir zeigen die Aussage zunächst für die leere Liste [].
Induktionsschritt (a:as): Wir nehmen an, daß die Aussage für die Liste as gilt, und
zeigen, daß sie unter dieser Voraussetzung auch für a:as gilt.
Beweisregel:
Φ([])
(∀a, as) Φ(as) =⇒ Φ(a:as)
(∀x) Φ(x)
Programmieren in Haskell
21
Spezifikation von insert:
ordered x = True =⇒ ordered (insert \(a\) \(x\)) = True
(7)
bag (insert a x) = *a+ ] bag x
(8)
Programmieren in Haskell
22
Φ(x)
⇐⇒
(∀a) bag (insert a x) = *a+ ] bag x
(9)
Induktionsbasis (x = []):
bag (insert a [])
Programmieren in Haskell
=
bag [a]
=
*a+ ] bag []
(Def. insert)
(Def. bag)
23
⇐⇒
Φ(x)
(∀a) bag (insert a x) = *a+ ] bag x
Induktionsschritt (x = a’:as):
Fall a <= a’ = True:
bag (insert a (a’:as))
Programmieren in Haskell
=
bag (a:a’:as)
=
*a+ ] bag (a’:as)
(Def. insert)
(Def. bag)
24
⇐⇒
Φ(x)
(∀a) bag (insert a x) = *a+ ] bag x
Induktionsschritt (x = a’:as):
Fall a <= a’ = False:
bag (insert a (a’:as))
=
bag (a’:insert a as)
=
*a’+ ] bag (insert a as)
=
=
=
Programmieren in Haskell
*a’+ ] (*a+ ] bag as)
*a+ ] (*a’+ ] bag as)
*a+ ] bag (a’:as)
(Def. insert)
(Def. bag)
(I.V.)
(Ass., Komm. ])
(Def. bag)
25
Φ(x)
⇐⇒
(∀a) ordered x = True =⇒ ordered (insert \(a\) \(x\)) = True
Induktionsbasis (x = []):
ordered (insert a [])
Programmieren in Haskell
=
ordered [a]
(Def. insert)
=
True
(Def. ordered)
26
Induktionsschritt (x = a’:as):
1. x = a1 :as ∧ a<=a1 = True
2. x = a1 :as ∧ a<=a1 = False ∧ as = []
3. x = a1 :as ∧ a<=a1 = False ∧ as = a2 :as0
Programmieren in Haskell
27
Φ(x)
⇐⇒
(∀a) ordered x = True =⇒ ordered (insert \(a\) \(x\)) = True
Teilfall a<=a2 = True:
ordered (insert a (a1 :as))
Programmieren in Haskell
=
ordered (a1 :insert a as)
(Def. insert)
=
ordered (a1 :a:as)
(Def. insert)
=
a1 <=a && a<=a2 && ordered as
(Def. ordered)
=
True
(Vor.)
28
Φ(x)
⇐⇒
(∀a) ordered x = True =⇒ ordered (insert \(a\) \(x\)) = True
Teilfall a<=a2 = False:
ordered (insert a (a1 :as))
=
ordered (a1 :insert a as)
(Def. insert)
=
ordered (a1 :a2 :insert a as0 )
(Def. insert)
=
a1 <=a2 && ordered (a2 :insert a as0 )
(Def. ordered)
=
ordered (a2 :insert a as0 )
=
ordered (insert a as)
(Def. insert)
=
True
(Vor. und I.V.)
Programmieren in Haskell
(Vor. undDef. (&&))
29
Strukturelle Induktion auf Bäumen
Induktionsbasis (Nil): Wir zeigen die Aussage für den leeren Baum Nil.
Induktionsbasis (Leaf a): Wir zeigen die Aussage für das Blatt Leaf a.
Induktionsschritt (Br l r): Wir nehmen an, daß die Aussage für den Teilbaum l und für
den Teilbaum r gilt, und zeigen, daß sie unter dieser Voraussetzung auch für den Baum
Br l r gilt.
Programmieren in Haskell
30
Strukturelle Induktion auf Bäumen
Induktionsbasis (Nil): Wir zeigen die Aussage für den leeren Baum Nil.
Induktionsbasis (Leaf a): Wir zeigen die Aussage für das Blatt Leaf a.
Induktionsschritt (Br l r): Wir nehmen an, daß die Aussage für den Teilbaum l und für
den Teilbaum r gilt, und zeigen, daß sie unter dieser Voraussetzung auch für den Baum
Br l r gilt.
Φ(Nil)
(∀a) Φ(Leaf a)
(∀l, r) Φ(l) ∧ Φ(r) =⇒ Φ(Br l r)
(∀t) Φ(t)
Programmieren in Haskell
30
Φ(t)
Programmieren in Haskell
⇐⇒
size t 6 2^depth t
31
Φ(t)
⇐⇒
size t 6 2^depth t
Induktionsbasis (t = Nil):
size Nil
=
1
(Def. size)
=
2^0
(Def. (^))
=
2^depth Nil
Programmieren in Haskell
(Def. depth)
31
Φ(t)
⇐⇒
Induktionsbasis (t = Nil):
size t 6 2^depth t
Induktionsbasis (t = Leaf a):
size Nil
size (Leaf a)
=
1
(Def. size)
=
1
(Def. size)
=
2^0
(Def. (^))
=
2^0
(Def. (^))
=
2^depth Nil
(Def. depth)
=
2^depth (Leaf a)
Programmieren in Haskell
(Def. depth)
31
⇐⇒
Φ(t)
size t 6 2^depth t
Induktionsschritt (t = Br l r):
size (Br l r)
Programmieren in Haskell
=
size l + size r
(Def. size)
6
2^depth l + 2^depth r
6
2 * 2^(max (depth l) (depth r))
(Eig. max)
=
2^(max (depth l) (depth r) + 1)
(Eig. (^))
=
2^depth (Br l r)
(I.V.)
(Def. depth)
32
Das allgemeine Induktionsschema
data T a1 . . . am = C1 t11 . . . t1n1 | . . . |Cr tr1 . . . trnr
Programmieren in Haskell
33
Das allgemeine Induktionsschema
data T a1 . . . am = C1 t11 . . . t1n1 | . . . |Cr tr1 . . . trnr
Seien li1 ,. . . , lipi mit 1 6 li1 < li2 < · · · < lipi 6 ni die Positionen, an denen der
Konstruktor Ci rekursiv ist
Programmieren in Haskell
33
Das allgemeine Induktionsschema
data T a1 . . . am = C1 t11 . . . t1n1 | . . . |Cr tr1 . . . trnr
Seien li1 ,. . . , lipi mit 1 6 li1 < li2 < · · · < lipi 6 ni die Positionen, an denen der
Konstruktor Ci rekursiv ist
(∀x11 . . . x1n1 ) Φ(x1l11 ) ∧ · · · ∧ Φ(x1l1p1 ) =⇒ Φ(C1 x11 . . . x1n1 )
...
(∀xr1 . . . xrnr ) Φ(xrlr1 ) ∧ · · · ∧ Φ(xrlrpr ) =⇒ Φ(Cr xr1 . . . xrnr )
(∀x) Φ(x)
Programmieren in Haskell
33
Spezialfall: Natürliche Induktion
data Natural = Zero | Succ Natural
Φ(Zero)
(∀n) Φ(n) =⇒ Φ(Succ n)
(∀n ∈ Nat) Φ(n)
Programmieren in Haskell
34
undepth
undepth
undepth
undepth
:: Tree a -> Integer
Nil
= 0
(Leaf _) = 0
(Br l r) = min (undepth l) (undepth r) + 1
Programmieren in Haskell
35
undepth
undepth
undepth
undepth
:: Tree a -> Integer
Nil
= 0
(Leaf _) = 0
(Br l r) = min (undepth l) (undepth r) + 1
Sei t ein Braun-Baum, dann gilt
depth t - undepth t ∈ {0, 1} .
Programmieren in Haskell
(10)
35
Induktionsbasis (t = Nil):
depth Nil - undepth Nil
=
0−0
=
0
∈
{0, 1}
(Def. depth, undepth)
Induktionsbasis (t = Leaf a):
depth (Leaf a) - undepth (Leaf a)
=
0−0
=
0
∈
{0, 1}
Programmieren in Haskell
(Def. depth, undepth)
36
Induktionsschritt (t = Br l r):
depth (Br l r) - undepth (Br l r)
=
max (depth l) (depth r) + 1 (min (undepth l) (undepth r) + 1)
(Def. depth, undepth)
=
Programmieren in Haskell
37
Verstärkung der Induktion
Programmieren in Haskell
2n 6 size t < 2n+1
=⇒
undepth t = n ,
(11)
2n−1 < size t 6 2n
=⇒
depth t = n .
(12)
38
Verstärkung der Induktion
2n 6 size t < 2n+1
=⇒
undepth t = n ,
(11)
2n−1 < size t 6 2n
=⇒
depth t = n .
(12)
Induktionsschritt (t = Br l r): Da t ein Braun-Baum ist, gilt size l = b 12 size tc
und size r = d 12 size te. Damit folgt für den linken Teilbaum
2n 6 size t < 2n+1
Programmieren in Haskell
=⇒
2n−1 6 size l < 2n
(Arithmetik)
=⇒
undepth l = n − 1
(I.V.)
38
und entsprechend für den rechten
2n 6 size t < 2n+1
=⇒
2n−1 6 size r 6 2n
(Arithmetik)
=⇒
undepth r > n − 1
(I.V.)
Insgesamt erhalten wir
undepth (Br l r)
Programmieren in Haskell
=
min (undepth l) (undepth r) + 1
=
n
(Def. undepth)
(obige Rechnungen)
39
Sortieren durch Fusionieren
[8, 3, 5, 3, 6, 1]
[8, 3, 5]
[3, 6, 1]
[3, 5]
8
3
5
[6, 1]
3
[3, 5]
[3, 5, 8]
6
1
[1, 6]
[1, 3, 6]
[1, 3, 3, 5, 6, 8]
Programmieren in Haskell
40
mergeSort :: (Ord a) => [a] -> OrdList a
mergeSort = sortTree . build
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) a = f (g a)
Programmieren in Haskell
41
Phase 2: Sortieren eines Binärbaums
sortTree
sortTree
sortTree
sortTree
Programmieren in Haskell
:: (Ord a)
Nil
=
(Leaf a) =
(Br l r) =
=> Tree a -> OrdList a
[]
[a]
merge (sortTree l) (sortTree r)
42
Phase 2: Sortieren eines Binärbaums
sortTree
sortTree
sortTree
sortTree
merge
merge
merge
merge
|
|
:: (Ord a)
Nil
=
(Leaf a) =
(Br l r) =
:: (Ord a) =>
[]
bs
(a:as) []
(a:as) (b:bs)
a <= b
otherwise
Programmieren in Haskell
=> Tree a -> OrdList a
[]
[a]
merge (sortTree l) (sortTree r)
OrdList a -> OrdList a -> OrdList a
= bs
= a:as
= a:merge as (b:bs)
= b:merge (a:as) bs
42
merge’ :: (Ord a) => OrdList a -> OrdList a -> OrdList a
merge’ []
= id
merge’ (a:as) = insert
where
insert []
= a:as
insert (b:bs)
| a <= b
= a:merge’ as (b:bs)
| otherwise = b:insert bs
Programmieren in Haskell
43
Programmieren in Haskell
ordered x ∧ ordered y =⇒ ordered (merge x y)
(13)
bag (merge x y) = bag x ] bag y
(14)
44
bag
bag
bag
bag
:: Tree a -> Bag a
Nil
= ∅
(Leaf a) = *a+
(Br l r) = bag l ] bag r
Programmieren in Haskell
45
bag
bag
bag
bag
:: Tree a -> Bag a
Nil
= ∅
(Leaf a) = *a+
(Br l r) = bag l ] bag r
Programmieren in Haskell
ordered (sortTree t)
(15)
bag (sortTree t) = bag t
(16)
45
bag (build x) = bag x
Programmieren in Haskell
(17)
46
bag (build x) = bag x
(17)
build :: [a] -> Tree a
build [] = Nil
build [a] = Leaf a
build as = Br (build (take k as)) (build (drop k as))
where k = length as ‘div‘ 2
Programmieren in Haskell
46
Phase 1: Konstruktion von Braun-Bäumen
type Braun a = Tree a
build’ :: [a] -> Braun a
build’ []
= Nil
build’ (a:as) = extend a (build as)
Programmieren in Haskell
47
Phase 1: Konstruktion von Braun-Bäumen
type Braun a = Tree a
build’ :: [a] -> Braun a
build’ []
= Nil
build’ (a:as) = extend a (build as)
extend :: a -> Braun a -> Braun a
extend a Nil
= Leaf a
extend a (Leaf b) = Br (Leaf b) (Leaf a)
Programmieren in Haskell
47
Phase 1: Konstruktion von Braun-Bäumen
type Braun a = Tree a
build’ :: [a] -> Braun a
build’ []
= Nil
build’ (a:as) = extend a (build as)
extend :: a -> Braun a -> Braun a
extend a Nil
= Leaf a
extend a (Leaf b) = Br (Leaf b) (Leaf a)
extend a (Br l r) = Br r (extend a l)
Programmieren in Haskell
47
1
0
0
(a)
(b)
3
2
0
4
(f)
Programmieren in Haskell
0
1
3
1
0
2
2
(c)
1
2
3
(d)
0
4
1
5
(e)
3
1
5
1
5
0
(g)
4
2
6
0
4
2
6
3
7
(h)
48
Programmieren in Haskell
bag (extend a t)
=
bag (build x)
=
*a+ ] bag t
bag x
(18)
(19)
braun t =⇒ braun (extend a t)
(20)
braun (build x)
(21)
49
Wohlfundierte Rekursion
build :: [a] -> Tree a
build [] = Nil
build [a] = Leaf a
build as = Br (build (take k as)) (build (drop k as))
where k = length as ‘div‘ 2
Programmieren in Haskell
50
Ist das Problem einfach, wird es mit ad-hoc Methoden gelöst. Anderenfalls
wird es in einfachere Teilprobleme aufgeteilt, diese werden nach dem
gleichen Prinzip gelöst und anschließend zu einer Gesamtlösung
zusammengefügt.
Programmieren in Haskell
51
Die Relation „≺“ heißt wohlfundiert, wenn es keine unendliche absteigende Kette
· · · ≺ xn ≺ · · · ≺ x2 ≺ x1
gibt.
Zum Beispiel auf N:
x≺y
x<y .
(22)
length x < length y .
(23)
⇐⇒
Auf Listen:
x≺y
Programmieren in Haskell
⇐⇒
52
leaves
leaves
leaves
leaves
leaves
leaves
:: Tree a -> [a]
Nil
(Leaf a)
(Br Nil r)
(Br (Leaf a) r)
(Br (Br l’ r’) r)
Programmieren in Haskell
=
=
=
=
=
[]
[a]
leaves r
a : leaves r
leaves (Br l’ (Br r’ r))
53
leaves
leaves
leaves
leaves
leaves
leaves
:: Tree a -> [a]
Nil
(Leaf a)
(Br Nil r)
(Br (Leaf a) r)
(Br (Br l’ r’) r)
weight
weight
weight
weight
:: Tree a -> Integer
Nil
= 0
(Leaf a) = 0
(Br l r) = 1+2*(size l - 1) + weight r
Programmieren in Haskell
=
=
=
=
=
[]
[a]
leaves r
a : leaves r
leaves (Br l’ (Br r’ r))
53
v
t
Programmieren in Haskell
u
=⇒
t
u
v
54
t≺u
Programmieren in Haskell
⇐⇒
weight t < weight u .
55
t≺u
⇐⇒
weight t < weight u .
weight (Br (Br l’ r’) r)
Programmieren in Haskell
=
2*size (Br l’ r’) + weight r - 1
(Def. weight)
=
2*size l’ + 2*size r’ + weight r - 1
(Def. size)
>
2*size l’ + 2*size r’ + weight r - 2
(Arithmetik)
=
2*size l’ + weight (Br r’ r) - 1
(Def. weight)
=
weight (Br l’ (Br r’ r))
(Def. weight)
55
Wohlfundierte Induktion
(∀y) ((∀z ≺ y) Φ(z)) =⇒ Φ(y)
(∀x) Φ(x)
Programmieren in Haskell
56
Herunterladen