ws 2002/2003 programmierung 1 - repetitorium andreas augustin und marc wagner

23
Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage: http://info1.marcwagner.info

Upload: hunter-goff

Post on 01-Jan-2016

25 views

Category:

Documents


0 download

DESCRIPTION

WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage: http://info1.marcwagner.info. Mittwoch, den 09.04.03 Kapitel 6 Konstruktortypen und Ausnahmen. 6.1 Varianten und Konstruktoren. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

WS 2002/2003

Programmierung 1 - Repetitorium

Andreas Augustin und Marc Wagner

Homepage: http://info1.marcwagner.info

Page 2: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

Mittwoch, den 09.04.03

Kapitel 6

Konstruktortypen und Ausnahmen

Page 3: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.1 Varianten und Konstruktoren

Ziel: Darstellung der drei geometrischen Formen Kreis, Quadrat und Dreieckals mathematische Objekte

Das Paar < 1 , r > stellt einen Kreis mit Radius r dar.

Das Paar < 2 , a > stellt ein Quadrat mit der Seitenlänge a dar.

Das Paar < 3 , < a , b , c > > stellt ein Dreieck mit den Seitenlängen a,b,c dar.

Die erste Komponente des Paares bezeichnet man als Variantennummer.Sie gibt die Form des geometrischen Objekts an.

Die zweite Komponente des Paares bezeichnet man als Datum.Sie spezifiziert die Dimensionen des geometrischen Objekts.

datatype shape = Circle of real | Square of real | Triangle of real * real * real

Page 4: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.1 Varianten und Konstruktoren

Der Datentyp shape liefert uns jetzt die Konstruktoren Circle, Square und Triangle.

Circle 4.0 Square 3.0 Triangle ( 4.0 , 3.0 , 5.0 )

Circle Square Triangle

4.0 3.0 4.0 3.0 5.0

Berechnung des Flächeninhalts :

fun area (Circle r) = Math.pi * r * r | area (Square a) = a * a | area (Triangle (a,b,c)) = let val s = (a+b+c)/2.0 in Math.sqrt(s*(s-a)*(s-b)*(s-c)) end

Page 5: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.1 Varianten und Konstruktoren

Die Prozedur area ist mit drei Regeln definiert, die jeweils für eine der dreiVarianten von shape zuständig sind.

Die Muster der Regeln haben die Form einer Konstruktoranwendung.

Die Deklaration von Konstruktoren ermöglicht es, die verschiedenen Varianteneines Konstruktortyps durch frei gewählte Namen zu bezeichnen.

Konvention:

Konstruktoren = Bezeichner mit Großbuchstaben beginnend

Typen und Werte = Bezeichner mit Kleinbuchstaben beginnend

Page 6: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.2 Enumerationstyp

datatype day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

Die Werte des Typs day werden durch nullstellige Konstruktoren beschrieben,die wie Konstanten verwendet werden können.

fun weekend Saturday = true | weekend Sunday = true | weekend _ = false

Typ: weekend : day → bool

map weekend [ Monday , Wednesday , Friday , Saturday, Sunday ] = [ false , false , false , true, true ]

Typen, die nur mit Hilfe von nullstelligen Konstruktoren definiert sind,werden als Enumerationstyp bezeichnet.

vordeklarierter Enumerationstyp: datatype order = LESS | EQUAL | GREATER

Page 7: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.3 Typsynonyme

type point = real * real

point ist hierbei kein neuer Typ, sondern eine neue Bezeichnung für einenbereits existierenden Typ.

sinnvolle Verwendungen :

datatype object = Circle of point * real | Triangle of point * point * point

Wir können auch einen neuen Typ einführen :

datatype point = P of real * real

P ( 2.0 , 3.0 ) : point

fun mirror ( P ( x , y ) ) = P ( ~x , y )

Page 8: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.4 Ausnahmen

Ausnahmen sind Werte des Typs exn.

Neue Ausnahmen deklariert man mithilfe von exception.

exception Newexception Newer of int

New sowie Newer sind Ausnahmekonstruktoren, diese können wie normaleKonstruktoren verwendet werden.

Zusätzlich kann man mit Ausdrücken der Form

raise e

die Ausnahme e werfen (e vom Typ exn)

raise Newer 6!Uncaught exception: Newer 6

Raise-Ausdrücke liefern keinen Wert, daher können sie jeden Typ annehmen.

Page 9: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.4 Ausnahmen

Geworfene Ausnahmen können mithilfe von Handle-Ausdrücken gefangen werden.

( raise New ) handle New => ( )( raise Newer 7 ) handle Newer x => 7fun test f = f() handle Newer x => x | Overflow => ~1

Beim Programmieren mit Ausnahmen sind manchmal Sequenzialisierungen( e1 ; ... ; en) hilfreich.

Auswertung einer Sequenz:Alle Teilausdrücke e1 , ... , en von links nach recht auswerten.Bei Terminierung aller Ausdrücke, liefert die Sequenz den Wert des letztenTeilausdrucks en.

(e1,...,en) = let val _ = e1

... val _ = en-1

in en

end

Page 10: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.5 Arithmetische Ausdrücke

type var = int (Variablen als ganze Zahlen)

datatype exp = C of int | V of var | A of exp*exp | M of exp*exp

Jede Ausdrucksform ( Konstante, Variable, Addition, Multiplikation ) wird durcheinen entsprechenden Konstruktor realisiert.

Darstellung der rekursiven Struktur von exp:

exp

int var

C V

MA

Page 11: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.5 Arithmetische Ausdrücke

( 2 x + y ) * ( x + 3 )

val e = M ( A ( M ( C 2 , V 1 ) , V 2 ) , A ( V 1 , C 3 ) )

M

A A

M V V C

C V 2 1 3

2 1

Um den Ausdruck auszuwerten, benötigen wir eine Umgebung,die den Variablen x und y Werte zuweist. { x → 5 , y → 3 }

val env = fn 1 => 5 | 2 => 3 | _ => raise Unbound

datatype exp = C of int| V of var| A of exp*exp| M of exp*exp

Page 12: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.5 Arithmetische Ausdrücke

Unser Ziel : die Evaluierungsprozedur eval : exp → env → int

fun eval ( C c ) _ = c | eval ( V v ) env = env v | eval ( A (e,e‘) ) env = eval e env + eval e‘ env | eval ( M (e,e‘) env = eval e env * eval e‘ env

Page 13: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.6 Optionen

datatype ‘a option = NONE | SOME of ‘a

NONE ist die uneingelöste Option, SOME ist die eingelöste Option.

fun get xs n = SOME (List.nth(xs,n)) handle Subscript => NONE

liefert das n-te Element einer Liste als eingelöste Option, wenn es existiert.

get [3,4,5] 2 = SOME 5get [3,4,5] 3 = NONE

fun valOf (SOME x) = x | valOf NONE = raise Option.Option

erlaubt bequemen Zugriff auf eingelöste Optionen

fun isSome NONE = false | isSome (SOME _) = true

testet, ob es sich um eine eingelöste Option handelt

Page 14: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.7 Case-Ausdrücke und abgeleitete Formen

fun sign x = case Int.compare (x,0) of LESS => ~1 | EQUAL => 0 | GREATER => 1

case e of M1 => e1 | ... | Mn => en = ( fn M1 => e1 | ... | Mn => en ) e

if e1 then e2 else e3 = (fn true => e2 | false => e3) e1

Page 15: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.8 Bäume informell und formal

Größe des Baumes = Anzahl der Knoten des Baumes

Pfad = Verbindung zwischen 2 bel. Knoten eines Baumes

Länge des Pfades = Anzahl der Kanten des Pfades

Tiefe des Knotens = Länge des Pfades von der Wurzel zu den Knoten

Tiefe des Baumes = Max. Tiefe seiner Knoten

3

14

2 7

2

1 3 0

Wurzel

Kante

Knoten

Marke

1.Nachfolger

2.Nachfolger 3.Nachfolger

Vorgänger

Blatt

Page 16: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.8 Bäume informell und formal

Eigenschaften von Bäumen :

1. Zwischen 2 Knoten eines Baumes existiert immer genau ein Pfad.

2. Die Wurzel eines Baumes hat keinen Vorgänger und alle anderen Knotenhaben genau einen Vorgänger.

Tiefe eines Knotens = Länge seiner Adresse

u Adresse des Knotens ⇒ u@[n] Adresse seines n-ten Nachfolgers

3

0 4 1

1 2 7 7

2 7 7

[ ]

[1] [2] [3]

[1,1] [3,1] [3,2] [3,3]

[1,1,1] [1,1,2] [1,1,3]

Page 17: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.8 Bäume informell und formal

Bäume mit genau einem Knoten heißen atomar.

Bäume mit mind. zwei Knoten heißen zusammenhängend.

Die Blätter eines Baumes sind alle Knoten ohne Nachfolger.

Jeder Baum hat genau eine Wurzel, mindestens ein Blatt und mind. einen Knoten.

Ein Baum ist aus seinem Kopf (Marke der Wurzel) und seinen Unterbäumen(Teilbäume der Nachfolger der Wurzel) zusammengesetzt. ( x , [ t1 , ... , tn ] )

1

2 7 7

( 1 , [ ( 2 , [ ] ) , ( 7 , [ ] ) , ( 7 , [ ] ) ] )

Ein Baum heißt linear gdw. jeder Knoten höchstens einen Nachfolger hat.

Ein Baum heißt binär gdw. jeder Knoten außer den Blättern genau zweiNachfolger hat.

Ein Baum heißt balanciert gdw. alle Blätter gleiche Tiefe haben.

Jeder atomare Baum ist linear, binär und balanciert.

Page 18: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.9 Ein ausführbares Modell für Bäume

datatype ‘a tree = T of ‘a * ( ‘a tree list )

1

2 7 7

T ( 1 , [ T ( 2 , [ ] ) , T ( 7 , [ ] ) , T ( 7 , [ ] ) ] )

fun head (T(x,_)) = x

fun dst (T(_,ts)) n = List.nth(ts,n-1)

liefert den Kopf des Baumes

liefert den n-ten Unterbaum von t

fun atomic (T(_,ts)) = null ts

testet, ob ein Baum atomar ist

Page 19: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.9 Ein ausführbares Modell für Bäume

fun subtree t nil = t | subtree t (n::ns) = subtree (dst t n) ns

fun node t ns = (subtree t ns; true) handle Subscript => false

fun leaf t ns = atomic (subtree t ns) handle Subscript => false

testet für einen Baum, ob es sich bei einer Liste um einen Knoten desBaumes handelt

testet für einen Baum, ob es sich bei einer Liste um ein Blatt des Baumes handelt

fun label t ns = head (subtree t ns)

liefert die Marke eines Knotens

liefert zu einem Baum und einer Liste den zugeordneten Teilbaum

fun pred t nil = raise Subscript | pred t ns = (subtree t ns; rev(tl(rev ns)))

liefert zu einem Baum und einem Knoten den Vorgänger des Knotens

Page 20: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.9 Ein ausführbares Modell für Bäume

fun succ t ns n = let val ns‘ = ns@[n] in subtree t ns‘; ns‘ end

fun size (T(_,ts)) = foldl op+ 1 (map size ts)

fun depth (T(_,ts)) = 1 + foldl Int.max -1 (map depth ts)

liefert die Größe eines Baumes ( = 1 + Summe der Größen seiner Unterbäume )

liefert die Tiefe eines Baumes ( = 1 + max. Tiefe seiner Unterbäume )

liefert zu einem Baum, einem Knoten und einer Zahl n den n-ten Nachfolger desKnotens

Page 21: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.10 Test auf Balanciertheit

Ein Baum ist genau dann balanciert, wenn für jeden seiner Teilbäume t gilt,dass alle seine Unterbäume die gleiche Höhe haben bzw. alle Blätter diegleiche Tiefe haben.

fun balanced t = let exception Unbalanced fun depthb (T(_,nil)) = 0 | depthb (T(_,t::tr)) = 1 + foldl forward (depth t) tr and forward (t,n) = if depthb t = n then n else raise Unbalanced in (depthb t; true) handle Unbalanced => false end

depthb und forward sind verschränkt rekursiv, daher ist eine Deklarationmit and erforderlich.

Page 22: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.11 Linearisation und Projektionen

Eine Liste heißt Linearisierung eines Baumes, wenn sie genau die Knoten desBaumes enthält (ohne Doppelauftreten), und wenn sie die Knoten jedesTeilbaumes als Segment enthält.

Die Projektion einer Liste von Knoten erhält man, indem man jeden Knotendurch seine Marke ersetzt.

Präfixlinearisierung :

1. Für jeden Teilbaum gilt : Die Wurzel erscheint vor den Knoten derUnterbäume.

2. Für jeden Teilbaum mit mindestens zwei Unterbäumen gilt :Die Knoten der Unterbäume erscheinen in der Reihenfolge der Unterbäume.

fun project t nss = map (label t) nss

fun pre (T(x,ts)) = x :: List.concat (map pre ts)

Page 23: WS 2002/2003 Programmierung 1 - Repetitorium  Andreas Augustin und Marc Wagner

Programmierung 1 - Repetitorium

6.11 Linearisation und Projektionen

Postfixlinearisierung :

fun post (T(x,ts)) = List.concat (map post ts) @ [x]

Analog zur Präfixlinearisierung, nur mit dem Unterschied, dass die Wurzeleines Teilbaums diesmal nach dem Knoten seiner Unterbäume erscheint.

3

2 7 7

0 4 1

5

Präfix : [ 3 , 0 , 5 , 4 , 1 , 2 , 7 , 7 ]

Postfix : [ 5 , 0 , 4 , 2 , 7 , 7 , 1 , 3 ]