• Keine Ergebnisse gefunden

Funktionales Programmieren Teil 9 Carl Philipp Reh

N/A
N/A
Protected

Academic year: 2021

Aktie "Funktionales Programmieren Teil 9 Carl Philipp Reh"

Copied!
13
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Funktionales Programmieren

Teil 9

Carl Philipp Reh

Universit¨ at Siegen

12. Juni 2020

(2)

Domains

Um denotationelle Semantik f¨ ur Haskell-Programme formal zu definieren, m¨ ussen wir zun¨ achst die Wertebereiche f¨ ur Typen festlegen. Diese werden Domains genannt. Jede Domain wird eine CPO sein. Dem Basistyp Int ordnen wir den Domain

D(Int) = Z ⊥ zu.

Welche Domains sollte man Data-Deklarationen zuordnen?

Betrachten wir

d a t a I n t P a i r = M a k e Int Int mit folgenden Beispielwerten

c :: I n t P a i r d :: I n t P a i r c = u n d e f i n e d

d = M a k e u n d e f i n e d u n d e f i n e d

Hier ist c komplett undefiniert, wohingegen d den Wertkonstruktor

(3)

Domains von Data-Deklarationen

Dass c und d sich anders verhalten, kann man gut an den folgenden beiden Funktionen erkennen:

f :: I n t P a i r - > Int f p = 0

g :: I n t P a i r - > Int

g p = c a s e p of M a k e x y - > 0

Wir haben, dass f c = 0 und f d = 0 . Ebenso haben wir g d = 0 . Allerdings terminiert g c nicht, weil es sein Argument so weit auswerten muss, bis klar ist, welcher Wertkonstruktor (hier M a k e ) angewandt wurde.

Wir ben¨ otigen also nicht nur ⊥-Werte f¨ ur die Argumente von

Wertkonstruktoren, sondern auch noch ein zus¨ atzliches ⊥ f¨ ur den

Fall, dass kein Wertkonstruktor angewandt wurde.

(4)

Weitere CPOs

Um die n¨ achsten CPO-Konstruktionen etwas zu vereinfachen, formulieren wir folgendes Lemma:

Lemma 12

Sei (D, v D ) eine CPO und c : N → D eine Kette.

1. Dann ist auch c k : N → D mit c k (n) = c (n + k) f¨ ur jedes k ∈ N eine Kette und es gilt tc k = tc.

2. Sei (E , v E ) eine CPO mit E ⊆ D, wobei v E die

Einschr¨ ankung von v D auf E ist, und sei Img(c) ⊆ E . Dann ist auch c E : N → E mit c E (n) = c (n) eine Kette und es gilt tc E = tc.

Beweis.

Wir haben Punkt 1 bereits f¨ ur k = 1 in der ¨ Ubung gezeigt. F¨ ur

k > 1 funktioniert die Argumentation analog. Punkt 2 ist klar.

(5)

Lift einer CPO (Teil 1)

Der Lift einer CPO (D, v D ) ist (D ⊥ , v D

) mit D ⊥ = D ] {⊥ D } und d v D

d 0 genau dann, wenn d = ⊥ D oder d , d 0 ∈ D mit d v D d 0 .

Lemma 13

(D ⊥ , v D

) ist eine CPO.

Beweis.

Reflexivit¨ at: Sei d ∈ D ⊥ . Wenn d = ⊥ D , dann gilt d v d . Wenn

d ∈ D, dann gilt d v D d , also auch d v d . Antisymmetrie: Seien

d , d 0 ∈ D ⊥ mit d v d 0 und d 0 v d . Wenn d = ⊥ D , dann gilt

d 0 v ⊥ D und somit muss d 0 = ⊥ D sein. Der Fall, dass d 0 = ⊥ D ,

ist analog. Wenn d , d 0 ∈ D, dann gilt d v D d 0 und d 0 v D d , also

auch d = d 0 . Transitivit¨ at: Seien d , d 0 , d 00 ∈ D ⊥ mit d v d 0 und

d 0 v d 00 . Wenn d = ⊥ D , dann gilt auch d v d 00 . Wenn d ∈ D,

dann gilt d v D d 0 . Daraus folgt d 0 ∈ D, also auch d 0 v D d 00 . Also

gilt d 0 v D d 00 und somit d v d 00 .

(6)

Lift einer CPO (Teil 2)

Beweis.

Nach Definition von v D

ist klar, dass ⊥ D das kleinste Element ist.

Sei c : N → D ⊥ eine Kette. Wir haben zwei F¨ alle zu unterscheiden:

Wenn c (n) = ⊥ D f¨ ur alle n ∈ N , dann ist c 0 : N → {⊥ D } mit

c 0 (d ) = c (d ) eine Kette und es gilt tc = tc 0 nach Punkt 2 von

Lemma 12. Ansonsten gibt es ein k ∈ N mit c (k) ∈ D. Nach

Definition von v D

muss dann f¨ ur alle k 0 > k gelten, dass

c(k 0 ) ∈ D. Also ist c 0 : N → D mit c 0 (n) = c(n + k ) eine Kette

und es gilt tc = tc 0 nach Punkten 2 und 1 von Lemma 12.

(7)

Domains von Data-Deklarationen

Wir betrachten zun¨ achst nicht rekursive Data-Deklarationen mit nur einem Wertkonstruktor: d a t a T C o n = V C o n. Solch ein Wertkonstruktor V C o n ist allgemein von der Form

V C o n = N T_1 ... T_n

wobei N ein Bezeichner ist und T_1 bis T_n f¨ ur n ≥ 0 Typen sind.

Werte, die mit N erzeugt wurden, sollen ein Element folgender Menge sein:

D(VCon) := {N} × D(T 1 ) × · · · × D(T n ) Die Menge {N} enth¨ alt nur einen Wert, der uns sagt, welcher Wertkonstruktor angewandt wurde. Da wir ein zus¨ atzliches ⊥ ben¨ otigen f¨ ur den Fall, dass kein Wertkonstruktor angewandt wurde, w¨ ahlen wir f¨ ur T C o n also

D(TCon) := D(VCon) = ({N} × D(T 1 ) × · · · × D(T n )) ⊥

(8)

Domains von Data-Deklarationen

Betrachten wir wieder

d a t a I n t P a i r = M a k e Int Int

Hier haben wir also

D(IntPair) = D(Make Int Int) = ({Make} × Z ⊥ × Z ⊥ ) ⊥

F¨ ur die vorherigen Werte c = u n d e f i n e d

d = M a k e u n d e f i n e d u n d e f i n e d

erhalten wir dann J c K = ⊥ und J d K = (Make, ⊥, ⊥). F¨ ur e = M a k e 0 1

erhalten wir J e K = (Make, 0, 1).

(9)

Domains f¨ ur mehrere Wertkonstruktoren

Als N¨ achstes betrachten wir Data-Deklarationen mit mehr als einem Wertkonstruktor. Die einfachste von diesen ist B o o l mit d a t a B o o l = T r u e | F a l s e

Wir haben D(True) = {True} und D(False) = {False} f¨ ur die beiden Wertkonstruktoren. Um beide Werte zusammenzuf¨ ugen, liften wir zun¨ achst die Domains und erhalten

D(True) = {True, ⊥} und D(False) = {False, ⊥}. Diese werden dann ¨ uber die verschmolzene Summe zusammengef¨ ugt, wo die beiden ⊥ von D(True) und D(False) identifiziert werden.

Wir werden außerdem aus technischen Gr¨ unden Elemente aus D(True) und D(False) mit

” Tags“ versehen, die sicher stellen,

dass nur disjunkte Mengen vereinigt werden.

(10)

Summe

Die Summe von n ≥ 0 Mengen M 1 , . . . , M n ist

M 1 + · · · + M n = (M 1 × {1}) ∪ · · · ∪ (M n × {n}).

Im Fall, dass n = 0, nehmen wir ∅. Die

” Tags“ 1, . . . , n stellen sicher, dass man f¨ ur jedes Element weiß, aus welcher Menge es gekommen ist, da die Mengen M 1 , . . . , M n nicht disjunkt sein m¨ ussen. Im Gegensatz zu Summen kann man bei der Vereinigung zweier Mengen diese Information verlieren, zum Beispiel bei N ∪ Z = Z . Der Name Summe kommt daher, dass

|A + B| = |A| + |B| f¨ ur alle Mengen A und B gilt. Wenn klar ist,

aus welcher Quellmenge ein Element (m, i) ∈ M i × {i } kommt,

schreiben wir auch einfach nur m.

(11)

Verschmolzene Summe

Seien (D 1 , v D

1

), . . . , (D n , v D

n

) CPOs. Die Verschmolzene Summe (D 1 ⊕ · · · ⊕ D n , v D

1

⊕···⊕D

n

) ist

D 1 ⊕ · · · ⊕D n = ((D 1 \ {⊥ D

1

}) +· · · + (D n \ {⊥ D

n

})) ∪ {⊥ D

1

⊕···⊕D

n

}, wobei d v D

1

⊕···⊕D

n

d 0 genau dann, wenn d = ⊥ D

1

⊕···⊕D

n

, oder d = (e, i ) ∈ (D i \ {⊥ D

i

}) × {i } und

d 0 = (e 0 , i) ∈ (D i \ {⊥ D

i

}) × {i} f¨ ur 1 ≤ i ≤ n mit e v D

i

e 0 . Wir entfernen also alle kleinsten Elemente aus D 1 , . . . , D n und f¨ ugen ein neues kleinstes Element hinzu.

Lemma 14

(D 1 ⊕ · · · ⊕ D n , v D

1

⊕···⊕D

n

) ist eine CPO.

Beweis.

Ubung. ¨

(12)

Domains f¨ ur mehrere Wertkonstruktoren

Im Fall von B o o l erhalten wir also

D(Bool) = D(True) ⊕ D(False)

= {True, ⊥} ⊕ {False, ⊥}

= ({True} + {False}) ∪ {⊥}

= {(True, 1), (False, 2), ⊥}

Da bei (True, 1) und (False, 2) klar ist, aus welcher Menge sie kamen, k¨ onnen wir stattdessen einfach True und False schreiben.

Grafisch ergibt sich folgende Ordnung:

True False

(13)

Domains f¨ ur mehrere Wertkonstruktoren

Allgemeiner sei

d a t a T C o n = V C o n _ 1 | ... | V C o n _ n wobei jedes V C o n _ i f¨ ur 1 ≤ i ≤ n mit n ≥ 0 einen

Wertkonstruktor deklariert. Auch hier erlauben wir zun¨ achst keine Rekursion. Wir ordnen T C o n folgenden Domain zu:

D(TCon) = D(VCon 1 ) ⊥ ⊕ · · · ⊕ D(VCon n ) ⊥

Da wir im Allgemeinen nur F¨ alle betrachten werden, wo die

Wertkonstruktornamen in den V C o n _ i verschieden sind, werden

wir die Tags in der Summe – wie wir es bei True und False getan

haben – ignorieren k¨ onnen.

Abbildung

Grafisch ergibt sich folgende Ordnung:

Referenzen

ÄHNLICHE DOKUMENTE

Zun¨ achst stellen wir fest, dass f¨ ur jede endliche Kette c : N → D das Supremum existiert, was das. ” letzte“ Element der Kette ist (Beweis:

Wenn man zeigen will, dass Funktionen stetig sind, kommt es oft vor, dass man mit mehreren Ketten auf einmal zu tun hat.. Diese Funktion ist stetig, weil sie

Er besagt, dass jede stetige Funktion einen kleinsten Fixpunkt hat und zeigt sogar, wie man diesen erh¨ alt..

Wir werden hierbei einige Einschr¨ ankungen vornehmen, die allerdings keine wirklichen Einschr¨ ankungen sind, da man alle anderen Haskell-Programme in unsere erlaubte Syntax

Wir m¨ ussten eigentlich noch zeigen, dass alle Funktionen, die wir in der Definition der Semantik benutzt haben, auch stetig sind.. Da dies allerdings sehr aufw¨ andig ist, m¨

Intuitiv geschieht dies, indem man Typvariablen so ersetzt, dass alle Typgleichungen von der Form τ = τ sind, also zum Beispiel α = Int wird zu Int = Int, indem man α durch

I ” nicht l¨ osbar“ liefert, wenn es keine L¨ osung f¨ ur E gibt, I und andernfalls eine allgemeinste L¨ osung f¨ ur E liefert.. Wir starten mit einer Substitution s, die am

Lehrstuhl Theoretische Informatik Carl Philipp Reh. Funktionales Programmieren