ALP I Funktionale Programmierung

Werbung
Algebraische Datentypen
ALP I
Funktionale Programmierung
Wiederholung
SS 2013
Prof. Dr. Margarita Esponda
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Funktionale Programmierung
Was haben wir bis jetzt gemacht?
Prof. Dr. Margarita Esponda
✴
Ausdrücke und Primitive Datentypen
✴
Funktionsdefinitionen
✴
Listen und Standardfunktionen für Listen
✴
List-Sequenzen, Listengeneratoren
✴
Tupel, Zeichenketten
✴
Einfache Rekursion und Endrekursion
✴
Such- und Sortieralgorithmen
✴
Funktionen höherer Ordnung
✴
Polymorphe Funktionen
✴
Algebraische und abstrakte Datentypen
✴
Haskell-Typsystem
Funktionale Programmierung
Was haben wir bis jetzt gemacht?
✴
Listen und Standardfunktionen für Listen
(:, ++, !!, length, take, drop, zip)
✴
List-Sequenzen, Listengeneratoren
Man muss Syntax und Semantik beherrschen
✴
Tupel, Zeichenketten
(fst, snd, curry, uncurry)
✴
Einfache Rekursion und Endrekursion
Rekursion → Endrekursion
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Was haben wir bis jetzt gemacht?
✴
Such- und Sortieralgorithmen
Komplexitätsanalyse von Funktionen
✴
Funktionen höherer Ordnung
Faltungsoperatoren als Abstraktionspattern bestimmter Art
von rekursiver Funktionen.
(foldr, foldl, map, filter, Funktionskomposition)
✴
Polymorphe Funktionen und Polymorphe Funktionen mit einem
Klassenkontext.
✴
Algebraische und abstrakte Datentypen
nicht rekursive und rekursive (Zahlen, Bäume)
✴
Haskell-Typsystem
Prof. Dr. Margarita Esponda
Wiederholungsbeispiel
Implementierung der Huffman-Kodierung in Haskell
(aus dem Buch von S. Thompson)
7 Module
HTypes.hs
Definition der Datentypen
Frequency.hs
Berechnung der Häufigkeiten
MakeTree.hs
MakeCode.hs
Erzeugung des H-Baums
CodeTable.hs
Tabelle für die Kodierung
Coding.hs
Definition der Hauptfunktionen
Main.hs
Zum Testen
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
HTypes.hs
Hier werden alle Datentypen definiert und exportiert
Huffman-Baum
module HTypes (
HTree (Leaf, Node),
für die Bitdarstellung
Bit (L, R),
HCode,
Datentyp der Endkodierung
HTable
)
where
Tabelle, die aus dem
Huffman-Baum erstellt wird.
data Bit = L | R
deriving (Eq, Show)
type HCode = [Bit]
type HTable = [ (Char, HCode) ]
data HTree = Leaf Char Int | Node Int HTree HTree
deriving (Show)
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
HTypes.hs
data HTree = Leaf Char Int | Node Int HTree HTree
deriving (Show)
data Bit = L | R
deriving (Eq, Show)
L
type HCode = [Bit]
type HTable = [ (Char, HCode) ]
[ ( 'T',
( 'W',
( 'A',
( 'N',
( 'R',
( 'D',
]
[L,L] ),
[L,R,L] ),
[L,R,R] ),
[R,L] ),
[R,R,L ),
[R,R,R] )
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
24
R
10
14
L
R
L
R
N
T
4
6
6
L
R
8
L
R
W
A
R
D
3
3
4
4
Frequency.hs
Allgemeine mergeSort-Funktion, die eine mergeFunktion als Argument bekommt.
module Frequency (frequency) -- [Char] -> [(Char,Int)]
where
mergeSort :: ([a]->[a]->[a])-> [a] -> [a]
mergeSort merge xs | (length xs < 2) = xs
| otherwise
= merge (mergeSort merge first)
(mergeSort merge second)
where
first = take half xs
second = drop half xs
half = (length xs) `div`2
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Frequency.hs
module Frequency (frequency)
where
…
alphaMerge :: [(Char, Int)] -> [(Char,Int)] -> [(Char,Int)]
alphaMerge xs [] = xs
alphaMerge [] ys = ys
alphaMerge ((p,n):xs) ((q,m):ys)
| (p==q)
| (p<q)
= (p,n+m) : alphaMerge xs ys
= (p,n) : alphaMerge xs ((q,m):ys)
| otherwise = (q,m) : alphaMerge ((p,n):xs) ys
Wenn zwei Tupel die gleichen Zeichen haben, werden sie
verschmelzt.
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Frequency.hs
module Frequency (frequency)
where
...
freqMerge :: [(Char, Int)] -> [(Char,Int)] -> [(Char,Int)]
freqMerge xs [] = xs
freqMerge [] ys = ys
freqMerge ((p,n):xs) ((q,m):ys)
| (n<m || (n==m && p<q)) = (p,n) : freqMerge xs ((q,m):ys)
| otherwise = (q,m) : freqMerge ((p,n):xs) ys
Die Tupels werden nach Häufigkeit sortiert. Wenn die Häufigkeit
gleich ist, dann werden die Tupels nach den Zeichen sortiert.
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Frequency.hs
module Frequency (frequency) -- [Char] -> [(Char,Int)]
where
...
frequency :: [Char] -> [(Char, Int)]
frequency = mergeSort freqMerge . mergeSort alphaMerge . map start
where
start ch = (ch,1)
frequency "WELCHE BUCHSTABEN WERDEN ..."
⇒ [('A',1),('D',1),('L',1),('R',1),('S',1),('T',1),('U',1),('B',2),('C',2),('H',2),
('N',2),('W',2),(' ',3),('.',3),('E',5)]
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Frequency.hs
frequency :: [Char] -> [(Char, Int)]
frequency = mergeSort freqMerge . mergeSort alphaMerge . map start
where
start ch = (ch,1)
frequency "WELCHE WELCHE ..."
⇒ (mergeSort freqMerge . mergeSort alphaMerge . map start) "WELCHE WELCHE ..."
⇒ mergeSort freqMerge (mergeSort alphaMerge (map start "WELCHE WELCHE ..."))
⇒ mergeSort freqMerge (mergeSort alphaMerge [('W',1),('E',1),('L',1)('C',1), ...])
⇒ mergeSort freqMerge [(' ',2),('.',3),('C',2),('E',4),('H',2),('L',2),('W',2)]
⇒ [(' ',2),('C',2),('H',2),('L',2),('W',2),('.',3),('E',4)]
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
MakeTree.hs
-- Prelude
curry :: ((a, b) -> c) -> a -> b -> c
-- curry converts an uncurried function to a curried function.
uncurry :: (a -> b -> c) -> (a, b) -> c
-- uncurry converts a curried function to a function on pairs.
f = curry g
g = uncurry f
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
MakeTree.hs
module MakeTree ( makeTree, toTreeList )
where
import HTypes ( HTree ( Leaf, Node ), Bit ( L, R ), HCode, HTable )
makeTree :: [(Char, Int)] -> HTree
makeTree = makeCodes . toTreeList
toTreeList :: [(Char, Int)] -> [HTree]
toTreeList = map (uncurry Leaf)
toTreeList [(' ',2),('C',2),('H',2),('L',2),('W',2),('.',3),('E',4)]
⇒ [Leaf ' ' 2, Leaf 'C' 2, Leaf 'H' 2, Leaf 'L' 2, Leaf 'W' 2, Leaf '.' 3, Leaf 'E' 4]
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Funktionale Programmierung
Erzeugung des Huffman-Baumes
[
L
P
V
?
M
B
U
I
W
A
S
C
H
R
D
T
N
_
E
1
1
1
1
2
2
2
2
3
3
4
4
4
4
4
4
6
9
14
]
[Leaf 'L' 1, Leaf 'p' 1, Leaf 'V' 1, Leaf '?' 1, Leaf 'M' 2, Leaf '.' 3, Leaf 'E' 4, . . . ]
data HTree = Leaf Char Int | Node Int HTree HTree
deriving (Show)
Prof. Dr. Margarita Esponda
MakeTree.hs
module MakeTree ( makeTree, toTreeList )
where
import HTypes ( HTree ( Leaf, Node ), Bit ( L, R ), HCode, HTable )
makeTree :: [(Char, Int)] -> HTree
makeTree = makeCodes . toTreeList
toTreeList :: [(Char, Int)] -> [HTree]
toTreeList = map (uncurry Leaf)
amalgamate :: [HTree] -> [HTree]
amalgamate (t1:t2:ts) = insertTree (join t1 t2) ts
makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (amalgamate ts)
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Funktionale Programmierung
Erzeugung des Huffman-Baumes
L
P
V
?
M
B
U
I
W
A
S
C
H
R
D
T
N
_
E
1
1
1
1
2
2
2
2
3
3
4
4
4
4
4
4
6
9
14
1. Die zwei Knoten mit den kleinsten Häufigkeiten in der Liste
werden extrahiert und deren Häufigkeiten addiert.
Amalgamate
2. Die Summe wird in einem neu erzeugten Knoten gespeichert,
der als linkes und rechtes Kind die zwei extrahierten Knoten hat.
join
V
?
M
B
U
I
W
A
S
C
H
R
D
T
N
_
E
1
1
2
2
2
2
3
3
4
4
4
4
4
4
6
9
14
2
L
P
1
1
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Erzeugung des Huffman-Baumes
V
?
1
1
2
L
P
1
1
M
B
U
I
W
A
S
C
H
R
D
T
N
_
E
2
2
2
2
3
3
4
4
4
4
4
4
6
9
14
insertTree
3. Zum Schluss wird die Wurzel des neuen
Binärbaums wieder in die Liste eingefügt.
Prof. Dr. Margarita Esponda
MakeTree.hs
...
join :: HTree -> HTree -> HTree
join t1 t2 = Node (freq1+freq2) t1 t2
where
freq1 = value t1
freq2 = value t2
value :: HTree -> Int
value (Leaf _ n ) = n
value (Node n _ _) = n
insertTree :: HTree -> [HTree] -> [HTree]
insertTree t [] = [t]
insertTree t (t1:ts) | value t < value t1 = t:t1:ts
| otherwise = t1 : insertTree t ts
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Funktionale Programmierung
Erzeugung des Huffman-Baumes
2
2
V
?
1
1
L
P
1
1
M
B
U
I
W
A
S
C
H
R
D
T
N
_
E
2
2
2
2
3
3
4
4
4
4
4
4
6
9
14
makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (amalgamate ts)
amalgamate :: [HTree] -> [HTree]
amalgamate (t1:t2:ts) = insertTree (join t1 t2) ts
Prof. Dr. Margarita Esponda
Erzeugung des Huffman-Baumes
2
2
V
?
L
P
1
1
1
1
M
B
U
I
W
A
S
C
H
R
D
T
N
_
E
2
2
2
2
3
3
4
4
4
4
4
4
6
9
14
makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (amalgamate ts)
amalgamate :: [HTree] -> [HTree]
amalgamate (t1:t2:ts) = insertTree (join t1 t2) ts
Prof. Dr. Margarita Esponda
Erzeugung des Huffman-Baumes
M
B
U
I
W
A
S
C
H
R
D
T
N
_
E
2
2
2
2
3
3
4
4
4
4
4
4
6
9
14
4
2
2
V
?
L
P
1
1
1
1
makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (amalgamate ts)
amalgamate :: [HTree] -> [HTree]
amalgamate (t1:t2:ts) = insertTree (join t1 t2) ts
Prof. Dr. Margarita Esponda
Erzeugung des Huffman-Baumes
M
B
U
I
W
A
2
2
2
2
3
3
4
2
S
C
H
R
D
T
N
_
E
4
4
4
4
4
4
6
9
14
2
V
?
L
P
1
1
1
1
makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (amalgamate ts)
amalgamate :: [HTree] -> [HTree]
amalgamate (t1:t2:ts) = insertTree (join t1 t2) ts
Prof. Dr. Margarita Esponda
Erzeugung des Huffman-Baumes
U
I
W
A
2
2
3
3
4
S
C
H
R
D
T
N
_
E
4
4
4
4
4
4
6
9
14
4
2
M
B
2
2
2
V
?
L
P
1
1
1
1
makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (amalgamate ts)
amalgamate :: [HTree] -> [HTree]
amalgamate (t1:t2:ts) = insertTree (join t1 t2) ts
Prof. Dr. Margarita Esponda
Erzeugung des Huffman-Baumes
U
I
W
A
2
2
3
3
4
4
M
B
2
2
2
S
C
H
R
D
T
N
_
E
4
4
4
4
4
4
6
9
14
2
V
?
L
P
1
1
1
1
makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (amalgamate ts)
amalgamate :: [HTree] -> [HTree]
amalgamate (t1:t2:ts) = insertTree (join t1 t2) ts
Prof. Dr. Margarita Esponda
Erzeugung des Huffman-Baumes
[
]
41
30
E
16
14
24
17
_
8
C
H
4
4
4
V
?
L
P
1
1
1
1
14
N
T
4
2
10
9
S
2
Prof. Dr. Margarita Esponda
8
8
4
6
4
4
6
8
U
I
M
B
W
A
R
D
2
2
2
2
3
3
4
4
Erzeugung des Huffman-Baumes
[
]
71
41
30
E
16
14
24
17
_
8
8
8
makeCodes :: [HTree] -> HTree
C
H
S
2
V
?
L
P
1
1
1
1
14
N
T
makeCodes [t] = t
4
4
4
4
4 ts)4
makeCodes ts = makeCodes (amalgamate
2
10
9
6
4
6
8
U
I
M
B
W
A
R
D
2
2
2
2
3
3
4
4
Erzeugung des Huffman-Baumes
71
41
30
E
16
14
24
17
_
8
C
H
4
4
8
8
S
4
2
V
?
L
P
1
1
1
1
14
N
T
4
2
10
9
4
6
4
4
6
8
U
I
M
B
W
A
R
D
2
2
2
2
3
3
4
4
Coding.hs
module CodeTable ( codeTable )
where
import HTypes
codeTable :: HTree -> HTable
codeTable = convert []
where
convert :: HCode -> HTree -> HTable
convert hc (Leaf c n) = [(c, hc)]
convert hc (Node n tl tr) = (convert (hc++[L]) tl) ++
(convert (hc++[R]) tr)
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Kodierung der Zeichen
codeTable
Der Code jedes
71
L
convert
Zeichens wird aus
dem Weg von der
Wurzel des Baumes
30
bis zu dem
convert L
R convert
entsprechenden
E
Buchstaben aus
16
14
den Kanten
convert
L
R convert
abgelesen.
L
8
17
L
H
4
4
R convert
24
convert
L
R
8
R
L
S
4
convert
R
10
9
R
R
L
convert 14
L
4
R
2
L
RL
R
V
?
L
P
1
1
1
1
L
RL
U
I
M
2
2
2
convert
6
4
4
R
N
T
4
2
41
_
R L
L
Prof. Dr. Margarita Esponda
convert
L
8
C
convert
R convert
6
8
L
R
L
R
B
W
A
R
D
2
3
3
4
4
R
convert
convert
Coding.hs
module CodeTable ( codeTable )
where
import HTypes
codeTable :: HTree -> HTable
codeTable = convert []
where
convert :: HCode -> HTree -> HTable
convert hc (Leaf c n) = [(c, hc)]
convert hc (Node n tl tr) = (convert (hc ++ [L]) tl) ++
(convert (hc ++ [R]) tr)
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Kodierung der Zeichen
Der Code jedes
Zeichens wird aus dem
Weg von der Wurzel
des Baumes bis zu
dem entsprechenden
L
Buchstaben aus den
E
Kanten abgelesen.
14
[ ('E', [L, L]),
('_', [L, R, L]),
('C ', [L, R, L, L]),
.
L
codeTable
71
L
30
L
R
L
16
L
R L
H
4
4
.
L
S
4
R
10
9
R
14
R
L
L
4
R
2
('P', [L,R,R,L,R,R])
L
RL
R
]
V
?
L
P
1
1
1
1
L
RL
U
I
M
2
2
2
6
4
4
R
N
T
4
2
24
L
R
8
R
L
R
_
8
C
41
17
R
8
.
Prof. Dr. Margarita Esponda
R
6
8
L
R
L
R
B
W
A
R
D
2
3
3
4
4
R
Coding.hs
Hauptfunktionen für die Codierung
und Decodierung von Nachrichten.
module Coding ( code, decode )
where
import HTypes ( HTree ( Leaf, Node ), Bit ( L, R ), HCode, HTable )
code :: HTable -> [Char] -> HCode
code htable = concat . map (lookup htable)
lookup :: HTable -> Char -> HCode
lookup [] c
= error "lookup..."
lookup ((char, hc):rtable) c | char == c
| otherwise
...
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
= hc
= lookup rtable c
Dekodierung
0010110010111010111100101
E
71
0
1
30
0
0
1
41
1
E
14
16
0
24
17
1
0
0
1
1
_
0
8
8
1
C
H
4
4
0
0
S
4
1
2
0
2
1 0
1
V
?
L
P
1
1
1
1
Prof. Dr. Margarita Esponda
10
9
1
14
1
0
4
1 0
N
6
4
1
1
0
T
4
4
0
0
8
1
6
8
0
1
0
1
U
I
M
B
W
A
R
D
2
2
2
2
3
3
4
4
Coding.hs
Hauptfunktionen für die Codierung
und Decodierung von Nachrichten.
module Coding ( code, decode )
...
decode :: HTree -> HCode -> [Char]
decode htree = decodeByte htree
where
decodeByte (Node n t1 t2) (L:rest) = decodeByte t1 rest
decodeByte (Node n t1 t2) (R:rest) = decodeByte t2 rest
decodeByte (Leaf c n) rest = c:decodeByte htree rest
decodeByte t [] = []
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Dekodierung
0010110010111010111100101
E
71
0
1
30
0
_
0
1
41
1
E
14
16
0
24
17
1
0
0
1
1
_
0
8
8
1
C
H
4
4
0
0
S
4
1
2
0
2
1 0
1
V
?
L
P
1
1
1
1
Prof. Dr. Margarita Esponda
10
9
1
14
1
0
4
1 0
N
6
4
1
1
0
T
4
4
0
0
8
1
6
8
0
1
0
1
U
I
M
B
W
A
R
D
2
2
2
2
3
3
4
4
Dekodierung
0010110010111010111100101
E
71
0
M
1
30
0
_
0
1
41
1
E
14
16
0
24
17
1
0
0
1
1
_
0
8
8
1
C
H
4
4
0
0
S
4
1
2
0
2
1 0
1
V
?
L
P
1
1
1
1
Prof. Dr. Margarita Esponda
10
9
1
14
1
0
4
1 0
N
6
4
1
1
0
T
4
4
0
0
8
1
6
8
0
1
0
1
U
I
M
B
W
A
R
D
2
2
2
2
3
3
4
4
Dekodierung
0010110010111010111100101
_
E
_
M
N
H
N
71
0
Damit die Information später
dekodiert werden kann, muss
1
30
0
0
1
der dazu gehörige Huffman-
41
Baum in der komprimierten
Datei beinhaltet sein.
1
E
14
16
0
24
17
1
0
0
1
1
_
0
8
8
1
C
H
4
4
0
0
S
4
1
2
0
2
1 0
1
V
?
L
P
1
1
1
1
Prof. Dr. Margarita Esponda
10
9
1
14
1
0
4
1 0
N
6
4
1
1
0
T
4
4
0
0
8
1
6
8
0
1
0
1
U
I
M
B
W
A
R
D
2
2
2
2
3
3
4
4
MakeCode.hs
module MakeCode ( codes, codeTable )
where
import HTypes ( HTree ( Leaf, Node ), Bit ( L, R ), HCode, HTable )
import Frequency ( frequency )
import MakeTree ( makeTree )
import CodeTable ( codeTable )
codes :: [Char] -> HTree
Hier werden die Häufigkeiten
und der Huffman-Baum
erzeugt.
codes = makeTree . frequency
codes "WELCHE WELCHE …"
⇒ Node 17 (Node 8 (Leaf 'E' 4) (Node 4 (Leaf ' ' 2) (Leaf 'C' 2))) (Node 9
(Node 4 (Leaf 'H' 2) (Leaf 'L' 2)) (Node 5 (Leaf 'W' 2) (Leaf '.' 3)))
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Main.hs
module Main where
import HTypes ( Tree(Leaf,Node), Bit(L,R), HCode, HTable )
import Coding ( code, decode )
import MakeCode ( codes, codeTable )
import Frequency ( frequency )
import MakeTree( makeTree, toTreeList )
...
Alle Module werden hier
importiert, um die einzelnen
Funktionen testen zu können.
code htree "WELCHE WELCHE ..."
⇒
[R,R,L,L,L,R,L,R,L,R,R,R,L,L,L,L,L,R,L,R,R,L,L,L,R,L,R,L,R,R,R,L,L,L,L,L,R,L,
R,R,R,R,R,R,R,R,R]
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Main.hs
module Main where
import HTypes ( Tree(Leaf,Node), Bit(L,R), HCode, HTable )
import Coding ( code, decode )
import MakeCode ( codes, codeTable )
import Frequency ( frequency )
import MakeTree( makeTree, toTreeList )
...
decode
Alle Module werden hier
importiert, um die einzelnen
Funktionen testen zu können.
htree [R,R,L,L,L,R,L,R,L,R,R,R,L,L,L,L,L,R,L,R,R,L,L,L,R,L,R,L,
R,R,R,L,L,L,L,L,R,L,R,R,R,R,R,R,R,R,R]
⇒ "WELCHE WELCHE ..."
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
Funktionale Programmierung
Lokale Variablennamen
Es gibt in Haskell eine zweite Möglichkeit, lokale Variablen zu
definieren mit Hilfe des let-in-Ausdrucks.
Allgemeine Form:
let Lokale Definitionen
in
Beispiel:
f x y =
let
Ausdruck
a = x+y*2
b = x-y/2
in (a+b*b)
f x y =
Prof. Dr. Margarita Esponda
x + y*2 + (x-y/2)*(x-y/2)
Funktionale Programmierung
Lokale Variablennamen
Beispiele:
u = let a = 2
b = a + ( let a = 3
b=c
in a+b )
c = a^2
in b*b
u n = let a = 2*n
b = a + ( let a = 3
b=c
in a+b )
c = a^2
in b*b
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Wichtige Hinweise für die Zwischenklausur:
1) Schreiben Sie in allen Funktionen die entsprechende
Signatur.
2) Verwenden Sie die vorgegebenen Funktionsnamen, falls
diese angegeben werden.
3) Die Zwischenklausur muss geheftet bleiben.
4) Schreiben Sie Ihre Antworte in den dafür vorgegebenen
freien Platz, der unmittelbar nach der Frage steht.
ALP I: Margarita Esponda, 17. Vorlesung, 02.12.2012
44
Zugehörige Unterlagen
Herunterladen