Abstrakte Datentypen 1

Werbung
2. Abstrakte Datentypen
2.0 Begriffe
Geheimnisprinzip:
(information hiding principle, Parnas 1972)
Zugriffe auf Teile einer Programmeinheit, die für die
„reguläre Benutzung“ nicht erforderlich sind,
sollten verboten sein.
Besser:
Die nicht benötigten Teile sollten unsichtbar sein.
Warum??
hs / fub – alp3 –ADT-1 1
Warum Datenabstraktion?
Vorteile
1 Sicherheit:
Objekt kann nicht in ungültige Zustände gebracht werden.
2 Komfort:
Benutzer kann von Repräsentation abstrahieren;
Objekt wird ausschließlich über Operationen benutzt.
3 Flexibilität:
Code der Klasse kann unabhängig vom benutzenden Code
entwickelt werden - und ohne Auswirkungen auf den
benutzenden Code geändert werden.
hs / fub – alp3 –ADT-1 2
1
Datenabstraktion
Datenabstraktion:
(data abstraction)
Anwendung des Geheimnisprinzips auf die Darstellung
von (einfachen und komplexen) Daten im Rechner:
die Daten sind nicht durch Zugriff auf ihre Bestandteile,
sondern ausschließlich über zugehörige Operationen
manipulierbar.
[ Auch „Datenkapselung“ (data encapsulation) ]
hs / fub – alp3 –ADT-1 3
Abstrakte Datentypen (ADT)
2.2 Spezifikation von Abstrakten Datentypen
Sichtbare Schnittstelle:
Typbezeichner
Signaturen der Operationen
Spezifikation der Operationen
Abstraktionsbarriere
Implementierung
unsichtbar für Klient
muss Spezifikation genügen!
was heißt das? Verifikation?
meist viele Implementierungen möglich
gleiche funktionale Eigenschaften
nichtfunktionale (wie Laufzeiteffizienz )
oft drastisch unterschiedlich
hs / fub – alp3 –ADT-1 4
2
Spezifikation von ADT
Grundsätze
Keine Annahmen über Implementierung des Typs
Methodensignaturen ("Prozedurköpfe") festlegen
Semantik der Methoden festlegen
- Kann formal oder umgangssprachlich erfolgen
- Präzise muss es sein
Zwei
Verfahren
Algebraische Spezifikation
Modellierende Spezifikation
Modell zugrunde legen, Voraussetzungen, zu erzielende
Effekte, Invarianten darin spezifizieren
Ähnlich wie bisher: Modell war Zustandsraum, allerdings
implementierungsabhängig !
Besser: Natürliche Zahlen, Mengen, Listen, ....
Wichtig: Spezifizierende und Implementierer müssen
gleiches Verständnis des Modells haben ("gleiche
Semantik")
hs / fub – alp3 –ADT-1 5
Spezifikation von ADT
2.2.1 Algebraische Spezifikation
ADT wird festgelegt durch:
Wertemengen (Typen, Sorten)
Signaturen der Operationen
--------------------------------Definierende Gleichungen
Syntax
Semantik
legen Beziehungen zwischen Operationen fest
hs / fub – alp3 –ADT-1 6
3
Stack (algebraisch)
types
Stack, T, Bool , Int
// repräsentiert durch Typen
operators
createStack :
-> Stack
push: T -> Stack -> Stack
pop : Stack
-> Stack
top : Stack
-> T
size : Stack
-> Int
axioms ....
hs / fub – alp3 –ADT-1 7
Stack (algebraisch)
axioms
for all x ∈ T, s ∈ Stack :
pop ( push (x , s ) ) = s
top (push (x , s ) ) = x
size (createStack) = 0
size (push (x , s ) ) = 1 + size (s)
Einzige Möglichkeit zur Charakterisierung von
Stack-Objekten sind Axiome
hs / fub – alp3 –ADT-1 8
4
Stack (algebraisch)
Kanonische Darstellungen
Viele Darstellungen repräsentieren den gleichen Wert
push( y (pop ( push (x , createStack)))) =
push (y, createStack)
Axiome als Ersetzungsregeln (rewrite rules)
Systematische Ersetzung -> kanonische Darstellung
hs / fub – alp3 –ADT-1 9
Stack (algebraisch): Haskell
Signatur
Stack: algebraic specification in Haskell
(executable)
> module Stack (Stack, createStack, push,
>
pop, top, size, isEmpty)
> where
>
>
>
>
>
createStack :: Stack t
push :: t -> Stack t -> Stack t
pop :: Stack t -> Stack t
top :: Stack t -> t
size :: Stack t -> Int
hs / fub – alp3 –ADT-1 10
5
Stack (algebraisch): Haskell
> data Stack t = EmptyStack
| NES t (Stack t)
>
deriving (Show)
> createStack = EmptyStack
> push x s
= NES x s
> pop
> pop
EmptyStack
(NES x s)
= error "stack underflow"
= s
> top
> top
EmptyStack
(NES x s)
= error "stack underflow, no top"
= x
> size EmptyStack
> size (NES x s )
= 0
= 1 + size s
> isEmpty st
= size st==0
hs / fub – alp3 –ADT-1 11
Stack Anwendung: Klammergebirge
Aufgabe: Prüfe, ob ein Ausdruck "richtig"
geklammert ist.
Beispiel: "( () ( ) (( )) )" ok
"( ( ( ) (( ) ) )" nein
Definition korrekter Klammerausdrücke:
- eine Zeichenkette (auch leere möglich)
ohne Klammern ist korrekt.
- Sind S1, S2, S3 korrekt, dann auch S1 (S2) S3.
- Das sind alle korrekten Klammerausdrücke.
hs / fub – alp3 –ADT-1 12
6
Stack Anwendung: Klammergebirge
Haskell-Programm
"Korrekte Klammern"
simpel application of stacks: ..
> import Stack
>
>
>
>
>
>
>
>
>
>
>
>
checkBrack :: String -> Bool
checkBrack str = checkStack EmptyStack str
checkStack :: (Stack Char) -> String -> Bool
checkStack st []
| isEmpty st
= True
| otherwise
= False
checkStack st (c:rest)
| c=='('
= checkStack (push '(' st) rest
| c==')'
=
if (isEmpty st) then False
else checkStack (pop st) rest
| otherwise = checkStack st rest
hs / fub – alp3 –ADT-1 13
7
Herunterladen