Praktische Informatik 3: Funktionale Programmierung Vorlesung 9 vom 09.12.2012: Signaturen und Eigenschaften
Christoph Lüth Universität Bremen Wintersemester 2014/15
Rev. 2840 1 [25]
Fahrplan
I Teil I: Funktionale Programmierung im Kleinen
I Teil II: Funktionale Programmierung im Großen
IAbstrakte Datentypen
ISignaturen und Eigenschaften
ISpezifikation und Beweis
I Teil III: Funktionale Programmierung im richtigen Leben
2 [25]
Abstrakte Datentypen und Signaturen
I Letzte Vorlesung:Abstrakte Datentypen
I TypplusOperationen
I Heute:SignaturenundEigenschaften
Definition (Signatur)
DieSignatureines abstrakten Datentyps besteht aus den Typen, und der Signatur der darüber definierten Funktionen.
I Keine direkte Repräsentation in Haskell I Signatur:Typeines Moduls
3 [25]
Endliche Abbildung: Signatur
I AdressenundWertesindParameter
dataMapα β I Leere Abbildung:
empty :: Mapα β I Abbildung auslesen:
lookup :: Ordα⇒α→Mapα β→Maybeβ I Abbildung ändern:
i n s e r t :: Ordα⇒α→β→Mapα β→Mapα β I Abbildung löschen:
delete :: Ordα⇒α→Mapα β→Mapα β
4 [25]
Signatur und Eigenschaften
I Signatur genug, um ADTtypkorrektzu benutzen
I InsbesondereAnwendbarkeitundReihenfolge
I Signatur beschreibt nicht dieBedeutung(Semantik):
I Waswirdgelesen?
I Wieverhältsich die Abbildung?
I Signatur istSprache(Syntax) umEigenschaftenzu beschreiben
5 [25]
Beschreibung von Eigenschaften
Definition (Axiome)
AxiomesindPrädikateüber denOperationender Signatur
I ElementarePrädikateP:
IGleichheits == t
IOrdnungs<t
ISelbstdefinierte Prädikate I ZusammengesetztePrädikate
INegationnot p
IKonjunktionp && q
IDisjunktionp| | q
IImplikationp =⇒q
6 [25]
Beobachtbare und Abstrakte Typen
I BeobachtbareTypen: interne Struktur bekannt
I Vordefinierte Typen (Zahlen,Zeichen), algebraische Datentypen (Listen)
I Viele Eigenschaften und Prädikate bekannt I AbstrakteTypen: interne Struktur unbekannt
I Wenige Eigenschaften bekannt, Gleichheit nur wenn definiert
I BeispielMap:
I beobachtbar: Adressen und Werte
I abstrakt: Speicher
7 [25]
Axiome als Interface
I Axiome müssengelten
IfüralleWerte der freien Variablen zuTrueauswerten I Axiomespezifizieren:
Inach außen dasVerhalten
Inach innen dieImplementation I Signatur+Axiome=Spezifikation
Spezifikation
Implementation Nutzer
rich thin interface
8 [25]
Thin vs. Rich Interfaces
I Benutzersicht:reichesInterface
I Viele Operationen und Eigenschaften I Implementationssicht:schlankesInterface
I Wenig Operation und Eigenschaften I BeispielMap:
I Rich interface:
i n s e r t :: Ordα⇒α→β→Mapα β→Mapα β delete :: Ordα⇒α→Mapα β→Mapα β
I Thin interface:
put :: Ordα⇒α→Maybeβ→Mapα β→Mapα β
I Thin-to-rich:
i n s e r t a v = put a ( Just v) delete a = put a Nothing
9 [25]
Axiome für Map
I Lesenaus leerer Abbildung undefiniert:
lookup a empty == Nothing
I Lesenan vorher geschriebener Stelle liefert geschriebenen Wert:
lookup a (put a v s ) == v I Lesenan anderer Stelle liefert alten Wert:
a6= b =⇒lookup a (put b v s ) == lookup a s I Schreibenan dieselbe Stelle überschreibt alten Wert:
put a w (put a v s ) == put a w s I Schreibenüber verschiedene Stellen kommutiert:
a6= b =⇒put a v (put b w s ) ==
put b w (put a v s ) Thin: 5 Axiome Rich: 13 Axiome
10 [25]
Axiome als Eigenschaften
I Axiome könnengetestetoderbewiesenwerden I Tests findenFehler, Beweis zeigtKorrektheit
E. W. Dijkstra, 1972
Program testing can be used to show the presence of bugs, but never to show their absence.
I Artenvon Tests:
I Unit tests(JUnit, HUnit)
I Black Boxvs.White Box
I Coverage-based(z.B. path coverage, MC/DC)
I ZufallsbasiertesTesten
I Funktionale Programme eignen sichsehr gutzum Testen
11 [25]
Zufallsbasiertes Testen in Haskell
I Werkzeug:QuickCheck
I Zufällige Werteeinsetzen, Auswertung aufTrueprüfen I Polymorphe Variablen nichttestbar
IDeshalb Typvariableninstantiieren
ITyp muss genug Element haben (hierMap Int String)
IDurch SignaturTypinstanzerzwingen
I Freie Variablender Eigenschaft werdenParameterder Testfunktion
12 [25]
Axiome mit QuickCheck testen
I Für das Lesen:
prop_readEmpty :: Int→ Bool prop_readEmpty a =
lookup a (empty :: Map Int String ) == Nothing prop_readPut :: Int→Maybe String→
Map Int String→ Bool prop_readPut a v s =
lookup a (put a v s ) == v I Eigenschaften alsHaskell-Prädikate
I Es werdenNZufallswerte generiert und getestet (N= 100)
13 [25]
Axiome mit QuickCheck testen
I BedingteEigenschaften:
IA =⇒BmitA,BEigenschaften
ITyp istProperty
IEs werden solange Zufallswerte generiert, bisNdie Vorbedingung erfüllende gefunden und getestet wurden, andere werden ignoriert.
prop_readPutOther :: Int→ Int→Maybe String→
Map Int String→ Property prop_readPutOther a b v s =
a6= b =⇒lookup a (put b v s ) == lookup a s
14 [25]
Axiome mit QuickCheck testen
I Schreiben:
prop_putPut :: Int→Maybe String→Maybe String→
Map Int String→ Bool prop_putPut a v w s =
put a w (put a v s ) == put a w s I Schreibenan anderer Stelle:
prop_putPutOther :: Int→Maybe String→ Int→
Maybe String→Map Int String→
Property prop_putPutOther a v b w s =
a6= b =⇒put a v (put b w s ) ==
put b w (put a v s )
I Test benötigtGleichheitundZufallswerte fürMap a b
15 [25]
Zufallswerte selbst erzeugen
I Problem:ZufälligeWerte vonselbstdefiniertenDatentypen
IGleichverteiltheitnicht immer erwünscht (e.g.[α])
IKonstruktionnicht immer offensichtlich (e.g.Map) I InQuickCheck:
ITypklasseclass Arbitrary αfürZufallswerte
IEigeneInstanziierungkann Verteilung und Konstruktion berücksichtigen
IE.g.KonstruktioneinerMap:
IZufällige Länge, dann aus sovielen zufälligen WertenMapkonstruieren
IZufallswerte in Haskell?
16 [25]
Signatur und Semantik
Stacks Typ:Stα Initialwert:
empty :: Stα Wert ein/auslesen:
push :: α→St α→ Stα top :: Stα→α pop :: Stα→ Stα Last in first out (LIFO).
Queues Typ:Quα Initialwert:
empty :: Quα Wert ein/auslesen:
enq :: α→Quα→Quα f i r s t :: Quα→α deq :: Quα→Quα First in first out (FIFO)
GleicheSignatur, unterscheidlicheSemantik.
17 [25]
Eigenschaften von Stack
I Last in first out (LIFO):
top (push a s ) == a pop (push a s ) == s push a s6= empty
18 [25]
Eigenschaften von Queue
I First in first out (FIFO):
f i r s t (enq a empty) == a
q6= empty =⇒ f i r s t (enq a q) == f i r s t q deq (enq a empty) == empty
q6= empty =⇒deq (enq a q) = enq a (deq q) enq a q6= empty
19 [25]
Implementation von Stack: Liste
Sehr einfach: ein Stack ist eine Liste
newtype Stα= St [α] deriving (Show, Eq) empty = St [ ]
push a (St s ) = St (a : s )
top (St [ ] ) = er ro r "St : ␣top␣on␣empty␣stack "
top (St s ) = head s
pop (St [ ] ) = er ro r "St : ␣pop␣on␣empty␣stack "
pop (St s ) = St ( t a i l s )
20 [25]
Implementation von Queue
I Mit einerListe?
I Problem: am Ende anfügen oder abnehmen ist teuer.
I DeshalbzweiListen:
I Erste Liste: zuentnehmendeElemente
I Zweite Liste:hinzugefügteElementerückwärts
I Invariante: erste Liste leer gdw. Queue leer
21 [25]
Repräsentation von Queue
Operation Resultat Queue Repräsentation
empty ([], [])
enq 9 9 ([9], [])
enq 4 4→9 ([9], [4])
enq 7 7→4→9 ([9], [7, 4])
deq 9 7→4 ([4, 7], [])
enq 5 5→7→4 ([4, 7], [5])
enq 3 3→5→7→4 ([4, 7], [3, 5])
deq 4 3→5→7 ([7], [3, 5])
deq 7 3→5 ([5, 3], [])
deq 5 3 ([3], [])
deq 3 ([], [])
deq er ro r ([], [])
22 [25]
Implementation
I Datentyp:
dataQuα= Qu [α] [α]
I Leere Schlange: alles leer empty = Qu [ ] [ ]
I Erstes Element steht vorne in erster Liste f i r s t :: Quα→α
f i r s t (Qu [ ] _) = er ro r "Queue: ␣ f i r s t ␣of␣empty␣Q"
f i r s t (Qu (x : xs ) _) = x I Gleichheit:
instance Eqα⇒Eq (Quα) where Qu xs1 ys1 == Qu xs2 ys2 =
xs1 ++ reverse ys1 == xs2 ++ reverse ys2
23 [25]
Implementation
I BeienqunddeqInvariante prüfen enq x (Qu xs ys ) = check xs (x : ys )
deq (Qu [ ] _ ) = er ro r "Queue: ␣deq␣of␣empty␣Q"
deq (Qu (_: xs ) ys ) = check xs ys
IPrüfung der Invariantenachdem Einfügen und Entnehmen
I checkgarantiertInvariante check :: [α]→ [α]→Quα check [ ] ys = Qu ( reverse ys ) [ ] check xs ys = Qu xs ys
24 [25]
Zusammenfassung
I Signatur: Typ und Operationen eines ADT I Axiome: über Typen formulierteEigenschaften I Spezifikation= Signatur + Axiome
I Interfacezwischen Implementierung und Nutzung
I Testenzur Erhöhung der Konfidenz und zum Fehlerfinden
I Beweisender Korrektheit
I QuickCheck:
I Freie Variablen der Eigenschaften werdenParameterder Testfunktion
I =⇒fürbedingteEigenschaften
25 [25]