Praktische Informatik 3: Einführung in die Funktionale Programmierung
Vorlesung vom 08.12.2010: Abstrakte Datentypen
Christoph Lüth & Dennis Walter Universität Bremen Wintersemester 2010/11
Rev. 1258 1 [31]
Fahrplan
I Teil I: Funktionale Programmierung im Kleinen
I Teil II: Funktionale Programmierung im Großen
IAbstrakte Datentypen
ISignaturen und Eigenschaften
IAktionen und Zustände
I Teil III: Funktionale Programmierung im richtigen Leben
2 [31]
Inhalt
IAbstrakte Datentypen
IAllgemeine Einführung
IRealisierung in Haskell
IBeispiele
3 [31]
Einfache Bäume
I Schon bekannt:Bäume data T r e e α = N u l l
| Node ( T r e e α) α ( T r e e α) I Dazu Test aufEnthaltensein:
member ’ :: Eq α⇒ α→ T r e e α→ B o o l member ’ _ N u l l = F a l s e
member ’ b ( Node l a r ) =
a == b | | member ’ b l | | member ’ b r I Problem: Sucheaufwändig(Backtracking)
I Besser: Baumgeordnet
INoch besser: Baumbalanciert
4 [31]
Geordnete Bäume
IVoraussetzung:
IOrdnung aufa(Ord a)
IEs soll für alle Bäume gelten:
∀x t.t= Node l a r−→ (member x l−→x<a)∧ (member x r−→a<x)
IBeispiel für eine Datentyp-Invariante ITest auf Enthaltensein vereinfacht:
member :: Ord α⇒ α→ T r e e α→ B o o l member _ N u l l = F a l s e
member b ( Node l a r )
| b <a = member b l
| a == b= True
| b >a = member b r
5 [31]
Geordnete Bäume
I Ordnungserhaltendes Einfügen
i n s e r t :: Ord α⇒ α→ T r e e α→ T r e e α i n s e r t a N u l l =Node N u l l a N u l l i n s e r t b ( Node l a r )
| b < a = Node ( i n s e r t b l ) a r
| b == a = Node l a r
| b > a = Node l a ( i n s e r t b r ) I Problem:Erzeugung ungeordneter Bäume möglich.
I Lösung: Versteckender Konstrukturen.
I Warum?E.g. Implementation von geordneten Mengen
6 [31]
Geordnete Bäume als abstrakter Datentyp
IEs gibt einenTypTree a IEs gibtOperationen
Iempty :: Ordα⇒Treeα
INichtNull :: Tree a, sonst Konstruktor sichtbar
I insert :: Ordα⇒α→Treeα→Treeα
Imember::Ordα⇒α→Treeα→Bool
I. . . undkeineweiteren!
IBeispiel für einenabstrakten Datentypen
IDatentyp-Invariantenkönnen außerhalb des definierenden Moduls nicht verletzt werden
7 [31]
Abstrakte Datentypen
Definition (ADT)
Einabstrakter Datentyp(ADT) besteht aus einem (oder mehreren) TypenundOperationenauf diesem.
I Werte des Typen können nur über die bereitgestellten Operationen erzeugt werden.
I Eigenschaften von Werten des Typen (insb. ihre innere Struktur) können nur über die bereitgestellten Operationen beobachtet werden.
ZurImplementationvon ADTs in einer Programmiersprache:
Möglichkeit derKapselungdurch I Module
I Objekte
8 [31]
ADTs in Haskell: Module
IEinschränkung der Sichtbarkeit durchVerkapselung IModul: Kleinste verkapselbareEinheit
IEinModulumfaßt:
IDefinitionenvon Typen, Funktionen, Klassen
IDeklarationder nach außensichtbarenDefinitionen ISyntax:
moduleName(sichtbare Bezeichner) whereRumpf
Isichtbare Bezeichnerkönnen leer sein
IGleichzeitig: Modul=ˆÜbersetzungseinheit (getrennte Übersetzung)
9 [31]
Beispiel: Exportliste für Bäume
I Export alsabstrakter Datentyp
moduleOrdTree (Tree, insert , member, empty)where
ITypTreeextern sichtbar
IKonstruktoren versteckt I Export alskonkreter Datentyp
moduleOrdTree (Tree(..), insert , member, empty)where
IKonstruktoren vonTreesind extern sichtbar
IPattern Matching ist möglich
IErzeugung auch von ungeordneten Bäumen möglich
10 [31]
Benutzung von ADTs
IOperationenundTypenmüssen bekannt gemacht werden (Import)
IMöglichkeiten des Imports:
IAllesimportieren
INur bestimmte Operationen und Typenimportieren
IBestimmteTypen und Operationen nicht importieren
11 [31]
Importe in Haskell
I Schlüsselwort:importName [hiding] (Bezeichner)
I Bezeichnergeben an,wasimportiert werden soll:
IOhne Bezeichner wirdallesimportiert
IMithidingwerden Bezeichnernichtimportiert
IAlle Importe stehen immer amAnfangdes Moduls
I Qualifizierter Import zur Vermeidung von Namenskollisionen
Iimport qualifiedNameasOtherName
IZ. B.import qualifiedData.Map as M
12 [31]
Beispiel: Importe von Bäumen
Import(e) Bekannte Bezeichner
import OrdTree Tree, insert, member, empty
import OrdTree(Tree, empty) Tree, empty import OrdTree(insert) insert
import OrdTree hiding (member) Tree, empty, insert import OrdTree(empty)
import OrdTree hiding (empty)
empty,
Tree, insert, member
13 [31]
Baumtraversion als Funktion höherer Ordnung
I Nützlich: Traversion als generisches fold
I Dadurch Iteration über den Baum möglich, ohne Struktur offenzulegen f o l d T :: (α→ β→ β→ β)→ β→ T r e e α→ β
f o l d T f e N u l l = e f o l d T f e ( Node l a r ) =
f a ( f o l d T f e l ) ( f o l d T f e r ) I Damit externe Definition von Aufzählung möglich:
enum :: Ord α⇒ T r e e α→ [α]
enum = f o l d T (λx l 1 l 2→ l 1++ x : l 2 ) [ ]
14 [31]
Schnittstelle vs. Implementation
IGleicheSchnittstellekann unterschiedlicheImplementationenhaben
IBeispiel: (endliche) Mengen
15 [31]
Endliche Mengen: Typsignaturen (1)
I Abstrakter Datentyp für endliche Mengen (polymorph über Elementtyp)
type S e t a I Leere Menge:
empty :: S e t a I Einfügen in eine Menge:
i n s e r t :: Ord a ⇒ a → S e t a → S e t a I Test auf Enthaltensein
member :: Ord a ⇒ a → S e t a → B o o l
16 [31]
Endliche Mengen: Typsignaturen (2)
ITest auf leere Menge n u l l :: S e t a → B o o l IVereinigung
u n i o n :: Ord a ⇒ S e t a → S e t a → S e t a ISchnittmenge
i n t e r s e c t i o n :: Ord a ⇒ S e t a → S e t a → S e t a IUmwandlung zu Listen
t o L i s t :: S e t a → [ a ]
f r o m L i s t :: Ord a ⇒ [ a ] → S e t a IMappen und Falten:
map :: ( Ord a , Ord b ) ⇒ ( a → b ) → S e t a → S e t b f o l d :: ( a → b → b ) → b → S e t a → b
17 [31]
Endliche Mengen: Eigenschaften
I Die leere Menge empty n u l l
n o t ( empty ( i n s e r t x s ) ) I Extensionalität
s1==s2⇔(∀x. member x s1⇔member x s2) I Einfügen und Enthaltensein
i n s e r t x ( i n s e r t y s ) == i n s e r t y ( i n s e r t x s ) member x ( i n s e r t x s )
I Schnittmenge
member x ( i n t e r s e c t i o n s 1 s 2 ) ==
member x s 1 && member x s 2 I Vereinigung
member x ( u n i o n s 1 s 2 ) ==
member x s 1 | | member x s 2
18 [31]
Endliche Mengen: Implementierung
IFür den Anwender vonData.Setirrelevant!
IWichtig aus Implementierungssicht:Effizienz IVerschiedene Möglichkeiten der Repräsentation
ISortierte Listen:typeSet a=[a]
IFunktionen:typeSet a=a→Bool
IIn der Tat verwendet: Balancierte Bäume dataSet a=Tip| Bin Int a (Set a) (Set a) (Intgibt die Größe des Baumes an.)
19 [31]
Endliche Abbildungen
I Eine Sichtweise: Ersatz für Hashtables in imperativen Sprachen.
Sehr nützlich!
I Abstrakter Datentyp für endliche Abbildungen (polymorph über Schlüssel- und Werttyp)
type Map a b I Leere Abbildung:
empty :: Map a b
I Hinzufügen eines Schlüssel/Wert-Paars
i n s e r t :: Ord a ⇒ a → b → Map a b → Map a b I Test auf Enthaltensein
member :: Ord a ⇒ a → Map a b → B o o l
20 [31]
Weitere Funktionen
ITest auf leere Abbildung n u l l :: Map a b → B o o l INachschlagen eines Werts
l o o k u p :: Ord a ⇒ a → Map a b → Maybe b ( ! ) :: Ord a ⇒ Map a b → a → b
ILöschen
d e l e t e :: Ord a ⇒ a → Map a b → Map a b IEinfügen und Duplikatkonflikte lösen
i n s e r t W i t h :: Ord a ⇒
( b → b → b ) → a → b → Map a b → Map a b
IMappen und Falten:
map :: ( b → c ) → Map a b → Map a c f o l d :: ( b → c → c ) → c → Map a b → c
21 [31]
Endl. Abbildungen: Anwendungsbeispiele
I Anzahl von Artikeln im Warenhaus
type Warehouse = Data . Map S t r i n g I n t n L e f t :: Warehouse → S t r i n g → I n t → B o o l n L e f t w a r t n =
c a s e s ‘ Data . Map . l o o k u p ‘ w o f N o t h i n g → F a l s e
J u s t m → m≥n
a d d A r t i c l e :: S t r i n g → I n t → Warehouse → Warehouse
a d d A r t i c l e a r t n w=
Data . Map . i n s e r t W i t h (+) a r t w
22 [31]
Weiterer Datentyp: Prioritätswarteschlangen
ISignatur von Prioritätswarteschlangen ähnlich Stacks und FIFO Queues:
type P r i o r i t y Q u e u e k a
ksteht für Priorität,aist eigentlicher Wert IOperationen:
Iempty::PriorityQueue k a
I null :: Ord k⇒PriorityQueue k a→Bool
I insert :: Ord k⇒k→a→PriorityQueue k a→PriorityQueue k a
IminKeyValue::Ord k⇒PriorityQueue k a→(k, a)
IdeleteMin :: Ord k⇒PriorityQueue k a→PriorityQueue k a
23 [31]
Implementierung mittels Heaps
I EinHeapist eine baumartige Datenstruktur mit derHeap-Eigenschaft:
IdataHeap k a=Nil| Branch k a (Heap k a) (Heap k a) h e a p P r o p :: Ord k⇒ Heap k a → B o o l h e a p P r o p N i l =True
h e a p P r o p ( B r a n c h k a l r ) = k ≤min ( minH k l ) ( minH k r )
&& h e a p P r o p l && h e a p P r o p r where minH k N i l =k
minH _ ( B r a n c h k a l r ) =
min k ( min ( minH k l ) ( minH k r ) )
I Wurzelelement jedes Teilbaums ist minimales Element des Teilbaums
24 [31]
Beispiel: Heap-Eigenschaft
IEin vollständiger binärer Baum mit Heap-Eigenschaft IKeingeordneter Baum
1
2 4
1 2 8 5 1 0
25 [31]
Binäre Heaps
I Vollständigkeitzusätzlich zur Heap-Eigenschaft d e p t h :: Ord k⇒ Heap k a → I n t d e p t h N i l = 0
d e p t h ( B r a n c h _ _ l r ) = 1 +max ( d e p t h l ) ( d e p t h r ) c o m p l e t e A t n N i l = F a l s e c o m p l e t e A t n ( B r a n c h _ _ l r ) =
i f n >0 then c o m p l e t e A t ( n − 1 ) l &&
c o m p l e t e A t ( n − 1 ) r e l s e n o t ( n u l l l ) && n o t ( n u l l r ) c o m p l e t e t = d< 3 | | c o m p l e t e A t ( d − 3 ) t
where d= d e p t h t
26 [31]
Beispiel: Vollständigkeit
IMit Knoten 8: vollständig
IOhne 8: höhenbalanciert, aber nicht vollständig
0
1 2
3 4 7 8
5 6
27 [31]
Operationen
I Exportierte Operationen:
s i n g l e t o n :: Ord k ⇒ k → a → Heap k a s i n g l e t o n k a = B r a n c h k a N i l N i l empty :: Heap k a
empty = N i l
i n s e r t :: Ord k ⇒ k → a → Heap k a → Heap k a i n s e r t k a N i l = s i n g l e t o n k a
i n s e r t k a ( B r a n c h k ’ a ’ l r )
| k < k ’ = B r a n c h k a ( i n s e r t k ’ a ’ r ) l
| o t h e r w i s e = B r a n c h k ’ a ’ ( i n s e r t k a r ) l m i n K e y V a l u e :: Ord k ⇒ Heap k a → ( k , a ) m i n K e y V a l u e ( B r a n c h k a _ _) = ( k , a )
28 [31]
Entfernen des minimalen Elements
IZum Entfernen: “Hochziehen” des jeweils kleineren Kindelements d e l e t e M i n :: Ord k ⇒ Heap k a → Heap k a d e l e t e M i n t =
c a s e t o f
B r a n c h _ _ N i l r → r B r a n c h _ _ l N i l → l
B r a n c h k a ( l @ ( B r a n c h l k l a _ _ ) ) ( r@ ( B r a n c h r k r a _ _ ) ) →
i f l k < r k then B r a n c h l k l a ( d e l e t e M i n l ) r e l s e B r a n c h r k r a l ( d e l e t e M i n r )
IBeispiele siehe../uebung/ueb06/trees.pdf
29 [31]
Effizienz
I Laufzeitverhalten:O(log(n))fürinsert unddeleteMin,O(1)für minKeyValue,singletonundempty.
I Pairing Heapsals Alternative zu Binären Heaps
IWorst-case Laufzeit fürdeleteMininO(n)
IAber: amortisierte Kosten inO(log(n))und in der Praxis erstaunlich schnell I Bsp.: 106zufällig priorisierte Elemente einfügen und entfernen
IHaskell: Laufzeit≈7s(im Vergleich:≈12.7sfür Binärheap)
IOCaml:≈3.3s
IJava (Binärer Heap als Array):≈3.6s I Tests auf 2GHz Intel Dual Core
30 [31]
Zusammenfassung
IAbstrakte Datentypen(ADTs):
IBesteht ausTypenundOperationendarauf IRealisierung in Haskell durchModule
IBeispieldatentypen: endliche Mengen und Abbildungen, Prioritätswarteschlangen
INächste Vorlesung: ADTs durchEigenschaftenspezifizieren
Vorlesung nächste Woche (15.12.2010)entfälltwegen Tag der Lehre!
Der Übungsbetriebfindet normal statt.
31 [31]