Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 1 Föreläsning 3: Abstrakta datatyper Algebror Abstrakta datatyper Inkapsling och informationsmaskering Parametrisering
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 2 Algebror Definition En algebra A är en tippel A = (D 1,…,D m, f 1,…,f n ) där varje D i är en mängd (kallad domän) och varje f j är en funktion f j mellan domäner (kallad operation), dvs f j :X 1 … X k Y där X 1,…,X k,Y {D 1,…,D m }. Vilka sorters data vill vi kunna prata om? … Vad kan vi göra med dem? …
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 3 Algebror mot program Tyvärr har program en mycket högre komplexitet. Varför? Ett av problemen: Andra delar i programmet kan utnyttja implementationsdetaljer som inte tillhör funktionaliteten. Ett program beskriver inte bara den abstrakta funktionaliteten utan i första hand – och i minsta detalj – hur den realiseras (= implementeras). korrektheten beror på godtyckliga ”slumpmässiga” antaganden varje liten detalj kan påverka vilken som helst annan del av programmet
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 4 Abstrakta datatyper Abstrakta datatyper (ADT:er) är ett försök att överföra algebror till programmeringen: Egenskaper hos data och operationer beskrivs abstrakt, dvs utan att lägga fast hur de implementeras Andra delar av programmet kan inte utnyttja implementationsdetaljer De här målen nås genom dataabstraktion Andra kan endast utnyttja de specificerade abstrakta egenskaperna (som inte förändras) istället för detaljer som beror på implementationen (och är tillfälliga)
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 5 Inkapsling och informationsmaskering För att uppnå målen måste ADT:er uppfylla två villkor: Inkapsling Definitionen av en ADT specificerar dess namn och vilka operationer som finns i en enda syntaktisk enhet (dvs är inte utspridd över flera ställen). Andra programdelar kan referera till definitionen för att använda ADT:n. Informationsmaskering (”information hiding”) Den interna representationen av data är inte tillgänglig för andra programdelar.
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 6 equations:isEmpty(empty) = true, isEmpty(push(s, e)) = false, pop(push(s, e)) = s,pop(empty) = error , top(push(s, e)) = e,top(empty) = error ADT stack is elem + boolean + operations:empty: stack push: stack x elem stack, pop: stack stack, top: stack elem, isEmpty: stack boolean Exempel på en formell specifikation Algebraisk specifikation av ADT:n stack
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 7 Exempel: stack i Java import java.util.*; class stack { private Vector s = new Vector(); public void push(elem e) { s.addElement(e); } public void pop() { s.removeElementAt(s.size() - 1); } public elem top() { return s.lastElement(); } public boolean isEmpty() { return s.size() = 0; } }
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 8 Parametriserade ADT:er Om en ADT bygger på andra, enklare ADT:er är det ofta önskvärt att kunna skapa olika instanser mha parametrar stack(integer), stack(tree), stack(stack(tree)), … sortedList(integer), sortedList(string), … …… Observera att de här parametrarna är datatyper! Problem: I vissa språk (t.ex. Java) är det inte möjligt att explicit skapa olika instanser sortedList(integer) och sortedList(string) hålls inte isär
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 9 Exempel: stack i ML exception EmptyStack abstype ‘a stack = Stack of ‘a list with val empty = Stack [] fun push (Stack s, e) = Stack (e::s) fun pop (Stack []) = raise EmptyStack | pop (Stack (_::xs)) = Stack xs fun top (Stack []) = raise EmptyStack | top (Stack (x::_)) = x fun isEmpty (Stack s) = s=[] end; val stack1 = push (empty, 1); > val stack1 = -:int stack val stack2 = push(push(empty,(1,”Otto”)),(2,”Olga”)); > val stack2 = -:(int*string)stack
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 10 Exempel: MinStack i HASKELL module MinStack ( MinStack, empty, push, pop, top, isEmpty, smallest ) where newtype (Ord a) => MinStack a = StackOf [a] empty :: (Ord a) => MinStack a empty = StackOf [] push (StackOf xs) x = StackOf (x : xs) pop (StackOf (x:xs)) = StackOf xs top (StackOf (x:xs)) = x isEmpty (StackOf xs) = xs == [] smallest (StackOf (x:xs)) = getSmallest x xs getSmallest x [] = x getSmallest x (y:ys) | x < y = getSmallest x ys | otherwise = getSmallest y ys syns parametern ska ha en ordningsrelation `<` syns inte! iStack :: MinStack Integer sStack :: MinStack String
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 11 ML:s modulbegrepp ML har ett ännu kraftfullare, generellare (och därmed svårbegripligt(?)) modulbegrepp: > Structures: paket med deklarationer > Signatures: typning av en struktur > Functors: parametriserade strukturer
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 12 Exempel: stack i ML igen signature StackItem = sig type item val isequal: item -> item -> bool end; signature Stack = sig type item type stack exception EmptyStack val empty: stack val push: (stack * item) -> stack o.s.v end; functor MkStack(Item:StackItem):> Stack = struct type myitem = Item.item type stack = myitem list exception EmptyStack val empty = [] fun push (s,e) = e::s.....o.s.v end;
Lennart Edblom, Frank Drewes, Inst. f. datavetenskap 13 Exempel: stack i ML igen (2) structure Pair:StackItem = struct type item = int * string fun isequal (i1,s1) (i1,s2) = i1=i2 andalso s1=s2 end; structure PairStack = MkStack(Pair); val mystack = PairStack.push (PairStack.empty, (3,”Haskell”));