Unendliche Listen - Otto-von-Guericke

Werbung
Unendliche Listen
Programmierparadigmen
Unendliche Listen
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
c
Sommer 2011, 26. April 2011, 2011
D.Rösner
D. Rösner PGP 2011 . . .
1
Unendliche Listen
Gliederung
1
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Verknüpfen mit zipWith
Filtern
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
D. Rösner PGP 2011 . . .
2
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
‘lazy evaluation’ (auf Deutsch: verzögerte Auswertung):
Werte werden nur bestimmt, wenn sie auch tatsächlich
benötigt werden
da in Haskell grundsätzlich ‘lazy’ evaluiert wird, werden für
unendliche Listen in Haskell keine zusätzlichen
Sprachmittel benötigt
Beispiel:
ones = 1:ones
Wie ist diese Definition zu lesen?
s.a. [Tho99], 17.6
D. Rösner PGP 2011 . . .
4
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
schrittweise Expansion der Definition von ones
ones = 1:ones
= 1:(1:ones)
= 1:(1:(1:ones))
...
-- Def.
-- Def.
-- Def.
damit zum Beispiel:
Main> head ones
1
Main> head (tail ones)
1
Main> take 10 ones
[1,1,1,1,1,1,1,1,1,1]
D. Rösner PGP 2011 . . .
5
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Welche Listenfunktionen können bei unendlichen Listen
angewendet werden?
fast alle!
ausgenommen sind nur solche Listenfunktionen, bei denen
die Berechnung eines Werts das Durchlaufen der ganzen
(endlichen) Liste erfordert
dazu gehören:
........................................
........................................
.....................................
.....................................
D. Rösner PGP 2011 . . .
7
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Welche Listenfunktionen können bei unendlichen Listen
angewendet werden?
alle Listenfunktionen, bei denen Werte in endlich vielen
Auswertungsschritten gewonnen werden können, lassen
sich wegen Haskells verzögerter Auswertung auf
unendliche Listen anwenden
dazu gehören auch die meisten Funktionen höherer
Ordnung
z.B. map, filter, zipWith, . . .
Welche Funktionen höherer Ordnung gehören nicht dazu?
.....................................
......................................
D. Rösner PGP 2011 . . .
9
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Erinnerung: paarweises Verknüpfen korrespondierender
Elemente zweier Listen
zipWith :: (a->b->c) -> [a]->[b]->[c]
zipWith z (a:as) (b:bs)
= z a b : zipWith z as bs
zipWith _ _
= []
_
D. Rösner PGP 2011 . . .
10
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
durch elementweises Verknüpfen lässt sich folgendes
definieren
Beispiel: unendliche Liste der natürlichen Zahlen
integers = 1: (zipWith (+) ones integers)
Wie ist diese Definition zu lesen?
Zugriff auf einen endlichen Abschnitt:
Main> take 10 integers
[1,2,3,4,5,6,7,8,9,10]
D. Rösner PGP 2011 . . .
11
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
schrittweise Expansion der Definition von integers
integers = 1: (zipWith (+) ones integers)
ones:
1 1 1 1 ...
integers:
ones:
1
1
1
1
1 ...
integers:
ones:
1
1
2
1
1
1 ...
integers:
ones:
1
1
2
1
3
1
1
-- zipWith: (+) 1 2
1 ...
integers:
...
1
2
3
4
-- zipWith: (+) 1 3
-- zipWith: (+) 1 1
D. Rösner PGP 2011 . . .
12
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Quadratzahlen
squares = map (\ x -> x*x) integers
Zugriffe:
Main> take 20 squares
[1,4,9,16,25,36,49,64,81,100,121,144,
169,196,225,256,289,324,361,400]
Main> head (filter (> 100000) squares)
100489
D. Rösner PGP 2011 . . .
13
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Kubikzahlen
Variante 1:
cubes = map (\ x -> x*x*x) integers
Variante 2:
cubes’ = (zipWith (*) squares integers)
Zugriff:
Main> take 10 cubes
[1,8,27,64,125,216,343,512,729,1000]
Main> head (filter (> 1000000) cubes)
1030301
D. Rösner PGP 2011 . . .
14
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Werte der Fakultätsfunktion
faks = 1: (zipWith (*) faks (tail integers))
Main> take 10 faks
[1,2,6,24,120,720,5040,40320,362880,3628800]
Damit auch möglich:
fak n = faks!!(n-1)
Anwendung:
Main> fak 3
6
Main> fak 10
3628800
D. Rösner PGP 2011 . . .
15
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Fibonacci-Zahlen
fibgen a b = a:(fibgen b (a + b))
fibs = fibgen 0 1
Zugriffe:
Main> take 10 fibs
[0,1,1,2,3,5,8,13,21,34]
Main> take 5 (filter (>10000) fibs)
[10946,17711,28657,46368,75025]
D. Rösner PGP 2011 . . .
16
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Filtern erzeugt unendliche Listen, deren Elemente eine
gewünschte Eigenschaft haben
Beispiel: unendliche Liste der nicht durch 7 teilbaren
Zahlen
divisiblep x y = mod x y == 0
no_sevens
= filter (\x -> not (divisiblep x 7)) [1 ..]
D. Rösner PGP 2011 . . .
17
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Wochentage
data Wochentag = Mo | Di | Mi | Do | Fr | Sa | So
deriving (Eq, Ord, Enum, Show, Read)
wochentage = [Mo ..] ++ wochentage
Main> take 30 wochentage
[Mo,Di,Mi,Do,Fr,Sa,So,Mo,Di,Mi,Do,Fr,Sa,
So,Mo,Di,Mi,Do,Fr,Sa,So,Mo,Di,Mi,Do,Fr,Sa,
So,Mo,Di]
D. Rösner PGP 2011 . . .
19
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
mögliche Verwendung: Kalender
Main> zipWith (showTag "Januar 2010")
(drop 4 wochentage) [1 .. 31]
liefert
["Fr 1. Januar 2010","Sa 2. Januar 2010","So 3. Januar 2010",
"Mo 4. Januar 2010","Di 5. Januar 2010","Mi 6. Januar 2010",
"Do 7. Januar 2010","Fr 8. Januar 2010","Sa 9. Januar 2010",
"So 10. Januar 2010","Mo 11. Januar 2010","Di 12. Januar 2010",
"Mi 13. Januar 2010","Do 14. Januar 2010","Fr 15. Januar 2010",
"Sa 16. Januar 2010","So 17. Januar 2010","Mo 18. Januar 2010",
"Di 19. Januar 2010","Mi 20. Januar 2010","Do 21. Januar 2010",
"Fr 22. Januar 2010","Sa 23. Januar 2010","So 24. Januar 2010",
"Mo 25. Januar 2010","Di 26. Januar 2010","Mi 27. Januar 2010",
"Do 28. Januar 2010","Fr 29. Januar 2010","Sa 30. Januar 2010",
"So 31. Januar 2010"]
D. Rösner PGP 2011 . . .
20
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Hilfsfunktion:
showTag
showTag monat
= (\ d n -> shows d
(showChar ’ ’
(shows n
(showChar ’.’
(showChar ’ ’ monat)))))
Beispiel für Verwendung:
Main> showTag "Februar 2009" Di 3
"Di 3. Februar 2009"
D. Rösner PGP 2011 . . .
21
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
unendliche Listen lassen sich oft auch als
Listenkomprehension schreiben
Beispiel: unendliche Liste aller pythagoräischen Tripel
Erinnerung: pythagoräische Tripel sind Tripel (x, y , z)
ganzer Zahlen, für die gilt:
x 2 + y 2 = z2
in Haskell (s.a. [Tho99], 17.6):
pythagTriples =
[(x,y,z)| z <- [2 .. ], y <- [2 .. z-1],
x <- [2 .. y-1], x*x + y*y == z*z]
D. Rösner PGP 2011 . . .
23
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Ausgabe einer solchen unendlichen Liste muss
abgebrochen werden:
Main> pythagTriples
[(3,4,5),(6,8,10),(5,12,13),(9,12,15),(8,15,17),(12,16,20),
(15,20,25),(7,24,25),(10,24,26),(20,21,29),(18,24,30),
(16,30,34),(21,28,35),(12,35,37),(15,36,39),(24,32,40),
(9,40,41),(27,36,45),(30,40,50),(14,48,50),(24,45,51),
(20,48,52),(28,45,53),(33,44,55),(40,42,58),(36,48,60),
(11,60,61),(39,52,65),(33,56,65),(25,60,65),(16,63,65),
(32,60,68),(42,56,70),(48,55,73),(24,70,74),(45,60,75),
(21,72,75),(30,72,78),(48,64,80),(18,80,82),(51,68,85),
(40,75,85),(36,77,85),(13,84,85),(60,63,87),(39,80,89),
(54,72,90),(35,84,91),(57,76,95),(65,72,97),(60,80,100),
(28,96,100),(20,99,101),(48,90,102),(40,96,104),(63,84,105),
(56,90,106),(60,91,109),(66,88,110),(36,105,111),(15,112,113),
(69,92,115),(80,84,116),(45,108,117),(56,105,119),(72,96,120),
(22,120,122),(27,120,123),(75,100,125),(44,117,125),(35,120,125),
(78,104,130),(66,112,130),(50,120,130),(32,126,130),(81,108,135),
D. Rösner PGP 2011 . . .
24
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Frage: kleinstes pythagoräisches Tripel, bei dem alle
Zahlen grösser als 1000?
Main> head (filter (\(x,_,_) -> x > 1000)
pythagTriples )
liefert (Warnung: Zeitbedarf):
(1020,1071,1479)
D. Rösner PGP 2011 . . .
25
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
die unendliche Liste der Potenzen einer natürlichen Zahl
Variante 1: Listenkomprehension
powers n = [n^x| x <- [0 ..]]
Variante 2: mit iterate
powers’ n = iterate (*n) 1
D. Rösner PGP 2011 . . .
27
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
aus Prelude.hs:
iterate
iterate f x
:: (a -> a) -> a -> [a]
= x : iterate f (f x)
Welche unendliche Liste wird durch iterate f x
erzeugt?
..................................................
D. Rösner PGP 2011 . . .
28
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Variante 3:
powers’’ n = 1:map (*n) (powers’’ n)
Was ist der Vorteil von Variante 3?
..................................................
D. Rösner PGP 2011 . . .
29
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
für viele Anwendungen (z.B. Simulationen) werden
Zufallszahlen benötigt
ein gängiges Verfahren zur Erzegung von
Pseudo-Zufallszahlen (engl. pseudo-random numbers) ist
die sog. lineare Kongruenzmethode (s.a. [Tho99], 17.6):
ausgehend von einem ganzzahligen Startwert (engl. seed)
werden aufeinanderfolgende Werte der Folge von
ganzzahligen Pseudo-Zufallszahlen dadurch berechnet,
dass
der jeweils aktuelle Wert mit einem Multiplikator
multipliziert,
dann zum Produkt ein Inkrement addiert und schliesslich
der Folgewert durch Bestimmung des Rests modulo einer
festen Zahl (dem sog. Modulus) gewonnen wird
D. Rösner PGP 2011 . . .
31
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
in Haskell:
nextRand n
= (multiplier*n + increment) ‘mod‘ modulus
randomSequence = iterate nextRand
Konsequenz: die Werte der Pseudo-Zufallsfolge liegen
zwischen 0 und modulus-1
D. Rösner PGP 2011 . . .
32
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
über ’günstige’ Werte für die Grössen Multiplikator,
Inkrement und Modulus gibt es Erfahrungswissen
eine mögliche Wertbelegung (s.a. [Tho99], 17.6):
seed
multiplier
increment
modulus
=
=
=
=
17489
25173
13849
65536
mögliche Nutzung:
Main> take 10 (randomSequence seed)
[17489,59134,9327,52468,43805,8378,18395,59344,
52777,23478]
D. Rösner PGP 2011 . . .
33
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
aus gleichverteilten Zufallszahlen im Bereich zwischen 0
und modulus-1 lassen sich durch Skalierung solche in
einem interessierenden Zahlenbereich gewinnen
z.B. Simulation eines Würfels:
Main> take 30 (scaleSequence 1 6
(randomSequence seed))
[2,6,1,5,5,1,2,6,5,3,3,2,1,3,3,6,2,4,4,1,
1,6,5,2,6,2,3,1,1,3]
D. Rösner PGP 2011 . . .
34
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
z.B. Simulation von Lottozahlen:
Main> take 30 (scaleSequence 1 49
(randomSequence seed))
[14,45,7,40,33,7,14,45,40,18,17,15,5,23,18,
46,11,26,31,4,5,46,35,10,44,14,19,3,2,21]
D. Rösner PGP 2011 . . .
35
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
bei der Skalierung auf Werte zwischen from und to (je
einschliesslich) wird der Bereich zwischen 0 und
Modulus-1 in to - from + 1 gleichgrosse Abschnitte
zerlegt
Zahlen aus dem jeweiligen Abschnitt wird dann der
korrespondierende Wert aus dem Bereich von from bis to
zugeordnet
D. Rösner PGP 2011 . . .
36
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
in Haskell:
scaleSequence from to
= map scale
where
scale n = from + n ‘div‘ denom
range = to - from + 1
denom = modulus ‘div‘ range
D. Rösner PGP 2011 . . .
37
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
gleichverteilte Zufallsfolgen für endliche Listen mit Werten
anderer Datentypen lassen sich ebenfalls leicht gewinnen
Skalierung für eine Liste von möglichen Werten:
uniformFrom list
= map (\n -> list!!(fromIntegral n))
(scaleSequence 0
(toInteger ((length list) - 1))
(randomSequence seed))
D. Rösner PGP 2011 . . .
38
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
Beispiel: Zufallsfolgen von Zeichen
Bereich [’a’ ..’z’]
Main> take 30 (uniformFrom [’a’ ..’z’])
"gxdurdhxujihcljyfnqccxsfxgkbak"
Bereich [’a’ ..’e’]
Main> take 30 (uniformFrom [’a’ ..’e’])
"beaedabeebbbacbebcdaaedbebbaac"
D. Rösner PGP 2011 . . .
39
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: Sieb des Eratosthenes
benannt nach Eratosthenes von Kyrene (ca. 276 v.Chr. –
194 v.Chr.), dem griechischen Mathematiker, Geograph,
Geschichtsschreiber, Philologe und Dichter sowie Direktor
der Bibliothek von Alexandria.
Idee:
a Streiche in der Liste aller natürlichen Zahlen alle Vielfachen
der gerade als Primzahl erkannten Zahl.
b Die erste der dann verbleibenden Zahlen ist wiederum prim.
c Wiederhole a.
D. Rösner PGP 2011 . . .
41
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: Sieb des Eratosthenes
Definition als Haskell-Funktion:
sieve [] = []
sieve (x:xs)
= x:(sieve (filter (\y -> not (divisiblep y x)) xs))
Alternative Definition:
sieve (x:xs)
= x:(sieve (filter (\y -> mod y x /= 0) xs))
D. Rösner PGP 2011 . . .
42
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Primzahlen
primes = sieve [2 ..]
D. Rösner PGP 2011 . . .
43
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Primzahlen
die ersten 100
Main> take 100 primes
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,
83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,
167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,
257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,
353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,
449,457,461,463,467,479,487,491,499,503,509,521,523,541]
D. Rösner PGP 2011 . . .
44
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Primzahlen
die erste Primzahl grösser als eine Schranke
Main> head (filter (> 1000) primes)
1009
Main> head (filter (> 10000) primes)
10007
Main> head (filter (> 5000) primes)
5003
D. Rösner PGP 2011 . . .
45
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
naheliegende Abstraktion: das beim Sieben
anzuwendende Prädikat wird zusätzliches Argument
m.a.W.:
sievep _ [] = []
sievep p (x:xs)
= x:(sievep p (filter (\y -> p y x) xs))
der Spezialfall des Sieb des Eratosthenes ergibt sich dann
als
primes’
= sievep (\a b -> mod a b /= 0) [2 ..]
D. Rösner PGP 2011 . . .
46
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Literatur: I
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
D. Rösner PGP 2011 . . .
47
Herunterladen