Praktische Informatik 3: Funktionale Programmierung Vorlesung 9 vom 11.12.2012: Signaturen und Eigenschaften
Christoph Lüth Universität Bremen Wintersemester 2012/13
Rev. 1922 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
IAktionen und Zustände
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
type Map α β I Leere Abbildung:
empty :: T r e e α I Abbildung auslesen:
l o o k u p :: Ord α⇒ α→ Map α β→ Maybe β I Abbildung ändern:
i n s e r t :: Ord α⇒ α→ β→ Map α β→ Map α β I Abbildung löschen:
d e l e t e :: 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:Sprache(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 α β d e l e t e :: Ord α⇒ α→ Map α β→ Map α β
I Thin interface:
p u t :: Ord α⇒ α→ Maybe β→ Map α β→ Map α β
I Thin-to-rich:
i n s e r t a v = p u t a ( J u s t v ) d e l e t e a= p u t a N o t h i n g
9 [25]
Axiome für Map
I Lesenaus leerer Abbildung undefiniert:
l o o k u p a empty == N o t h i n g
I Lesenan vorher geschriebener Stelle liefert geschriebenen Wert:
l o o k u p a ( p u t a v s ) == v I Lesenan anderer Stelle liefert alten Wert:
a 6=b =⇒ l o o k u p a ( p u t b v s ) == l o o k u p a s I Schreibenan dieselbe Stelle überschreibt alten Wert:
p u t a w ( p u t a v s ) == p u t a w s I Schreibenüber verschiedene Stellen kommutiert:
a 6=b =⇒ p u t a v ( p u t b w s ) ==
p u t b w ( p u t a v s ) Thin: 5 Axiome Rich: 13 Axiome
10 [25]
Axiome als Eigenschaften
I Axiome könnengetestetoderbewiesenwerden I Tests findenFehler, Beweis zeigtKorrektheit I Artenvon Tests:
I Unit tests(JUnit, HUnit)
I Black Boxvs.White Box
I Coverage-based(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:
p r o p _ r e a d E m p t y :: I n t→ B o o l p r o p _ r e a d E m p t y a =
l o o k u p a ( empty :: Map I n t S t r i n g ) == N o t h i n g p r o p _ r e a d P u t :: I n t→ Maybe S t r i n g→
Map I n t S t r i n g→ B o o l p r o p _ r e a d P u t a v s =
l o o k u p a ( p u t 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.
p r o p _ r e a d P u t O t h e r :: I n t→ I n t→ Maybe S t r i n g→ Map I n t S t r i n g→ P r o p e r t y p r o p _ r e a d P u t O t h e r a b v s =
a 6=b =⇒ l o o k u p a ( p u t b v s ) == l o o k u p a s
14 [25]
Axiome mit QuickCheck testen
I Schreiben:
p r o p _ p u t P u t :: I n t→ Maybe S t r i n g→ Maybe S t r i n g→ Map I n t S t r i n g→ B o o l
p r o p _ p u t P u t a v w s =
p u t a w ( p u t a v s ) == p u t a w s I Schreibenan anderer Stelle:
p r o p _ p u t P u t O t h e r :: I n t→ Maybe S t r i n g→ I n t→ Maybe S t r i n g→ Map I n t S t r i n g→ P r o p e r t y
p r o p _ p u t P u t O t h e r a v b w s = a 6= b =⇒ p u t a v ( p u t b w s ) ==
p u t b w ( p u t 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.[a])
IKonstruktionnicht immer offensichtlich (e.g.Map) I InQuickCheck:
ITypklasseclass Arbitrary afü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 :: S t α Wert ein/auslesen:
p u s h :: α→ S t α→ S t α t o p :: S t α→ α pop :: S t α→ S t α 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):
t o p ( p u s h a s ) == a pop ( p u s h a s ) == s p u s h a s 6= 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 q 6= empty
19 [25]
Implementation von Stack: Liste
Sehr einfach: ein Stack ist eine Liste
newtype S t α= S t [α] d e r i v i n g ( Show , Eq ) empty = S t [ ]
p u s h a ( S t s ) = S t ( a : s )
t o p ( S t [ ] ) = e r r o r " S t : ␣ t o p ␣ on ␣ empty ␣ s t a c k "
t o p ( S t s ) = he ad s
pop ( S t [ ] ) = e r r o r " S t : ␣ pop ␣ on ␣ empty ␣ s t a c k "
pop ( S t s ) = S t ( 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 error ([], [])
22 [25]
Implementation
I Datentyp:
data Quα =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 [ ] _) = e r r o r " Queue : ␣ f i r s t ␣ o f ␣ empty ␣Q"
f i r s t (Qu ( x : x s ) _) = x I Gleichheit:
i n s t a n c e Eq α⇒ Eq (Qu α) where Qu x s 1 y s 1 ==Qu x s 2 y s 2 =
x s 1 ++ r e v e r s e y s 1 == x s 2 ++ r e v e r s e y s 2
23 [25]
Implementation
I BeienqunddeqInvariante prüfen
enq x (Qu x s y s ) = c h e c k x s ( x : y s )
deq (Qu [ ] _ ) = e r r o r " Queue : ␣ deq ␣ o f ␣ empty ␣Q"
deq (Qu (_ : x s ) y s ) = c h e c k x s y s
IPrüfung der Invariantenachdem Einfügen und Entnehmen
I checkgarantiertInvariante c h e c k :: [α]→ [α]→ Qu α c h e c k [ ] y s =Qu ( r e v e r s e y s ) [ ] c h e c k x s y s =Qu x s y s
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]