Viel Erfolg! - Universität des Saarlandes

Werbung
IS
S
S A
R
E R S IT
S
UN
IV
A
Fachrichtung 6.2 — Informatik
Universität des Saarlandes
Tutorenteam der Vorlesung Programmierung 1
A VIE N
06.02.2016
Programmierung 1
Probeklausur zur Hauptklausur
Matrikelnummer:
• Bitte öffnen Sie das Klausurheft erst dann, wenn Sie dazu aufgefordert werden.
• Prüfen Sie dann zuerst, ob Sie alle 15 Seiten dieser Klausur erhalten haben.
• Hilfsmittel sind nicht zugelassen. Am Arbeitsplatz dürfen nur Schreibgeräte, Getränke, Speisen und
Ausweise mitgeführt werden. Taschen und Jacken müssen an den Wänden des Klausursaals zurückgelassen
werden. Mobiltelefone sind ebenfalls dort ausgeschaltet aufzubewahren.
• Das Verlassen des Saals ohne Abgabe des Klausurhefts gilt als Täuschungsversuch.
• Wenn Sie während der Bearbeitung zur Toilette müssen, geben Sie bitte Ihr Klausurheft bei der Aufsicht
ab. Zu jedem Zeitpunkt kann immer nur eine Person zur Toilette.
• Alle Lösungen müssen auf den bedruckten rechten Seiten des Klausurhefts notiert werden. Die leeren linken
Seiten dienen als Platz für Skizzen und werden nicht korrigiert. Notizpapier ist nicht zugelassen. Sie
können mit Bleistift schreiben.
• Vorhergehende Teilaufgaben dürfen verwendet werden, auch wenn sie nicht gelöst wurden.
• Für die Bearbeitung der Klausur stehen 120 Minuten zur Verfügung. Insgesamt können 120 Punkte und 10
Bonuspunkte erreicht werden. Zum Bestehen der Klausur genügen 60 Punkte.
• Bitte legen Sie zur Identifikation Ihren Personalausweis oder Reisepass sowie Ihren Studierendenausweis
neben sich.
Viel Erfolg!
Punkte
A1
25
A2
7
A3
15
A4
10
A5
15
A6
20
1
A7
13
A8
10
A9
5
Bonus
10
Gesamt
120 + 10
Matrikelnummer:
Seite 2 von 15
Sie dürfen folgende Strukturen verwenden:
Prozeduren:
• foldl : (α * β → β) → β → α list → β
• foldr : (α * β → β) → β → α list → β
• iter : int → α → (α → α) → α
• iterup : int → int → α → (int * α → α) → α
• iterdn : int → int → α → (int * α → α) → α
• first : int → (int → bool) → int
• map : (α → β) → α list → β list
• rev : α list → α list
• List.length : α list → int
• List.concat : α list list → α list
• List.tabulate : int * (int → α) → α list
• List.filter : (α → bool) → α list → α list
• List.exists : (α → bool) → α list → bool
• List.all : (α → bool) → α list → bool
• List.nth : (α list * int) → α
• hd : α list → α
• tl : α list → α list
• Int.compare : int * int → order
• null : α list → bool
• fold : (α list → α) → tree → α
• explode : string → char list
• implode : char list → string
• chr : int → char
• ord : char → int
• match : α * token list → token → α * token list
• extend : α * token list → (token list → β * token list) → (α * β → γ) → γ * token list
Datentypen:
• datatype tree = T of tree list
• Vector-Signatur:
eqtype α vector
val fromList: α list → α vector
val tabulate: int * (int → α) → α vector
val sub: (α vector * int) → α (*Subscript*)
val length: α vector → int
val map: (α → β) → α vector → β vector
val update = α vector * int * α → α vector
val foldl: (α * β → β) → β → α vector → β
val foldr: (α * β → β) → β → α vector → β
val concat: α vector list → α vector
Matrikelnummer:
Aufgabe 1: Zum Aufwärmen
Seite 3 von 15
(10 + 5 + 2 + 8 = 25) Punkte
Teilaufgabe 1.1
Schreiben Sie eine Prozedur sort: (α * α → order) → α list → α list, die eine Liste strikt aufsteigend
sortiert.
Teilaufgabe 1.2
Schreiben Sie eine Prozedur compare, die reine Bäume bezüglich ihrer Größe vergleicht.
Matrikelnummer:
Seite 4 von 15
Teilaufgabe 1.3
Schreiben Sie eine Prozedur vom Typ f: (α → β) * (γ → α) → γ → β ohne Verwendung von Konstanten
und expliziten Typangaben.
Teilaufgabe 1.4
Wie im Buch seien Umgebungen durch type α env = string → α definiert.
(a) Stellen Sie die leere Umgebung empty: α env dar.
exception Unbound of string
val empty =
(b) Schreiben Sie eine Prozedur update: α env → string → α → α env, die eine Umgebung um eine
zusätzliche Bezeichnerbindung erweitert.
(c) Stellen Sie die Umgebung [x := 42, y := 25] mithilfe von empty und update dar.
Matrikelnummer:
Seite 5 von 15
Aufgabe 2: Mathematische Prozeduren
(7) Punkte
Teilaufgabe 2.1
Zeigen Sie mithilfe des Korrektheitssatzes, dass die Prozedur
p:N→N
p n = if n < 1 then 1 else p(n − 1) + 2n + 1
die Funktion λn ∈ N.(n + 1)2 berechnet.
Matrikelnummer:
Seite 6 von 15
Aufgabe 3: Induktive Korrektheitsbeweise
(15) Punkte
Teilaufgabe 3.1
Zeigen Sie mit Hilfe von struktureller Induktion, dass ∀xs ∈ L(X) : foldl(f, nil, xs) = rev(map(g, xs)) mit
f = λ(x, xs) ∈ X × L(X). g(x) :: xs. Sie dürfen annehmen, dass die Konkatenation von Listen assoziativ ist, das
heißt xs@(ys@zs) = (xs@ys)@zs.
Die Definitionen von map und foldl seien wie folgt gegeben:
map ∈ (X → Y ) × L(X) → L(Y )
map(f, nil) = nil
map(f, x :: xs) = f (x) :: map(f, xs)
foldl ∈ ((X × Y ) → Y ) × Y × L(X) → (Y )
foldl(f, s, nil) = s
foldl(f, s, x :: xs) = foldl(f, f (x, s), xs)
Matrikelnummer:
Seite 7 von 15
Aufgabe 4: Laufzeit
(8 + 2 = 10) Punkte
Teilaufgabe 4.1
Bestimmen Sie die Komplexität folgender mathematischer Objekte. Begründen Sie Ihre Ergebnisse.
(a)
p:N×N×N→N
p(0, 0, z) = z
p(x, y, z) = if x > y then 5 · p(x − 1, y, z + x)
else x · x · x + p(x, y − 1, z + y)
für x > 0 oder y > 0
(b)
d∈N→N
d(n) = 2n
n < 500
n d(n) = 20 + d b c
2
n ≥ 500
Teilaufgabe 4.2
(a) Geben Sie die Komplexität der durch die folgende Gleichung rekursiv definierten Funktion f ∈ N → N an:
f (n) = if n = 0 then 0 else f (n − 1)
(b) Geben Sie die Komplexität der durch die folgende Gleichung rekursiv definierten Prozedur f : N → N an:
f (n) = if n = 0 then 0 else f (n − 1)
Matrikelnummer:
Seite 8 von 15
Aufgabe 5: Statische und dynamische Semantik
(15) Punkte
Es sei eine abstrakte Grammatik, Typen und Werte wie folgt gegeben:
fin
z∈Z
t ∈ T y = int
T ∈ TE = Id −−* Ty
x ∈ Id = N
e ∈ Exp = z | x | ++ e
v ∈ Val = Z
V ∈ VE = Id −−* Val
fin
Die obigen Ausdrücke, Typen, Werte und Umgebungen werden mit folgenden Typdeklarationen dargestellt:
datatype
datatype
datatype
datatype
exp = Num of int | Id of string | Increment of exp
ty = Int
value = IV of int
α env = string → α
Der Inkrement-Operator ist ein unärer Operator ++ : Z → Z, welcher eine ganze Zahl inkrementiert (also um
eins erhöht). So wertet beispielsweise ++ 5 zu 6 aus.
Teilaufgabe 5.1
(a) Vervollständigen Sie die Inferenzregeln für die statische Semantik.
SIncr
SNum
T `
SId
T `
T `
(b) Schreiben Sie nun eine Prozedur elab: ty env → exp → ty, welche nach obigen Inferenzregeln prüft,
ob ein Ausdruck wohlgetypt ist und dessen Typ zurückgibt.
Matrikelnummer:
Seite 9 von 15
Teilaufgabe 5.2
(a) Vervollständigen Sie die Inferenzregeln für die dynamische Semantik.
DIncr
DNum
V `
DId
V `
V `
(b) Schreiben Sie eine Prozedur eval: value env → exp → value, welche den Ausdruck nach obigen
Inferenzregeln auswertet.
Matrikelnummer:
Seite 10 von 15
Aufgabe 6: Konkrete Syntax
(3 + 10 + 7 = 20) Punkte
Es gibt zwei Operatoren für reguläre Ausdrücke: Kleene’scher Stern
•
∗
∗
und Vereinigung +.
klammert stärker als +.
• + klammert implizit links (wie die arithmetischen Operatoren auch).
•
∗
ist ein unärer Operator, d. h. ist ϕ ein regulärer Ausdruck, so ist ϕ∗ auch ein regulärer Ausdruck.
• + ist ein binärer Operator, d. h. sind ϕ und ψ reguläre Ausdrücke, so ist es auch ϕ + ψ.
Wortfolgen werden mit den folgenden Token dargestellt:
datatype token = STERN | PLUS | CON of string | LPAR | RPAR
Gültige Ausdrücke wären z.B. A + B + C ∗ , A∗ und (A + B)∗ . Konstanten sind also beliebige Strings.
Obige Regeln führen zu folgender Grammatik:
plusexp ::= [plusexp “+”] sternexp
sternexp ::= pexp [“*”]
pexp ::= con | “(”plusexp“)”
Hierbei bezeichnet con einen beliebigen String.
Teilaufgabe 6.1
Machen Sie die Grammatik RA-tauglich.
Matrikelnummer:
Seite 11 von 15
Teilaufgabe 6.2
Schreiben Sie einen Parser zu Ihrer Grammatik. Verwenden Sie dabei den folgenden Konstruktortyp exp:
datatype exp = Stern of exp | Plus of exp * exp | Con of string
Matrikelnummer:
Seite 12 von 15
Teilaufgabe 6.3
Wir betrachten eine Teilsprache von Standard ML, die nur aus beliebig geklammerten arithmetische Ausdrücken
gebildet mit Ganzzahlkonstanten und + besteht. Außerdem seien Kommentare erlaubt. Ein Kommentar beginnt
immer mit (* und endet mit *). Alles was zwischen Anfang und Ende des Kommentars steht, soll vom Lexer
ignoriert werden.
Schreiben Sie einen Lexer, der folgende Tokens aus einer char list ausliest.
datatype token = ADD | CON of int | LPAR | RPAR
fun lexInt s v cs = if null cs orelse not(Char.isDigit (hd cs))
then CON(s*v):: lex cs
else lexInt s (10*v+(ord(hd cs)−ord#"0")) (tl cs)
and lex
Matrikelnummer:
Aufgabe 7: Datenstrukturen
Seite 13 von 15
(4 + 9 = 13) Punkte
Teilaufgabe 7.1
(a) Implementieren Sie einen Konstruktortyp iLtr, welcher markierte Bäume darstellt. Es soll in konstanter
Zeit auf die Unterbäume zugegriffen werden können.
(b) Implementieren Sie nun eine Prozedur label: α iLtr → int list → α, welche die Markierung eines
markierten Baumes an einer Adresse liefert.
Teilaufgabe 7.2
Betrachten Sie die folgende Signatur für Mengen von ganzen Zahlen:
signature SET = sig
type set
val set
: int list → set
val Z
: set
val member : int → set → bool
val negate : set → set
end
set ist der Typ Ihrer Darstellung der Mengen.
Die Prozedur set verwandelt eine int list in ein endliches set; mit Z erhalten wir die Menge der ganzen
Zahlen. member implementiert ∈ und negate das Mengenkomplement. Das Komplement A einer Menge A ist
die Menge, die genau alle ganzen Zahlen enthält, die nicht in A sind.
Implementieren Sie eine Struktur, die diese Signatur realisiert.
Matrikelnummer:
Aufgabe 8: Speicher und veränderliche Objekte
Seite 14 von 15
(6 + 4 = 10) Punkte
Teilaufgabe 8.1
Schreiben Sie foldl mithilfe von map.
Teilaufgabe 8.2
Schreiben Sie einen Generator fgen: unit → int für die Kubikzahlen.
Aufgabe 9: Stapelmaschinen
(5) Punkte
Teilaufgabe 9.1
Schreiben Sie ein Maschinenprogramm, das folgenden Ausdruck auswertet: 18 + (2 + 34) · (7 − 3)
Matrikelnummer:
Aufgabe 10: Bonusaufgabe
Seite 15 von 15
(10) Bonuspunkte
Teilaufgabe 10.1
Beim Experimentieren mit Ihrem Interpreter sind Sie auf einen geheimnisvollen Typ blackbox gestoßen. Dieser
ist weder ein Typ mit Gleichheit noch haben Sie eine Vergleichsprozedur finden können. Allerdings steht Ihnen
eine Prozedur ssort: blackbox list → blackbox list zur Verfügung, die eine Liste von Elementen dieses
Typs strikt aufsteigend sortiert. Schreiben Sie damit eine Prozedur sort: blackbox list → blackbox list,
die eine Liste nicht-strikt sortiert.
Herunterladen