• Keine Ergebnisse gefunden

Semantik von Programmiersprachen Sommersemester 2012

N/A
N/A
Protected

Academic year: 2022

Aktie "Semantik von Programmiersprachen Sommersemester 2012"

Copied!
76
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Sommersemester 2012

Lehrstuhl f¨ ur Programmierparadigmen

Andreas Lochbihler andreas.lochbihler@kit.edu

(2)

1 Einf¨uhrung 5

1.1 Was ist eine Semantik? . . . 5

1.2 Warum formale Semantik? . . . 5

1.3 Operational, denotational und axiomatisch . . . 7

2 Die Sprache While 9 2.1 Syntax . . . 9

2.2 Zustand . . . 9

2.3 Semantik von Ausdr¨ucken . . . 10

3 Operationale Semantik f¨ur While 11 3.1 Big-Step-Semantik f¨urWhile. . . 11

3.2 Determinismus der Big-Step-Semantik . . . 12

3.3 Small-Step-Semantik f¨urWhile . . . 13

3.4 Aquivalenz zwischen Big-Step- und Small-Step-Semantik . . . .¨ 16

3.5 Aquivalenz von Programmen¨ . . . 17

4 Ein Compiler f¨ur While 19 4.1 Ein abstraktes Modell eines Rechners ASM . . . 19

4.2 Ein Compiler vonWhilenach ASM . . . 20

4.3 Korrektheit des Compilers . . . 20

4.4 Vergleich der verschiedenen Semantiken . . . 26

5 Erweiterungen von While 27 5.1 NichtdeterminismusWhileN D . . . 27

5.1.1 Big-Step-Semantik . . . 27

5.1.2 Small-Step-Semantik . . . 27

5.2 Parallelit¨atWhileP AR. . . 28

5.3 Bl¨ocke und lokale VariablenWhileB . . . 29

5.3.1 Big-Step-Semantik . . . 29

5.3.2 Small-Step-Semantik . . . 29

5.4 Ausnahmen WhileX . . . 30

5.4.1 Small-Step-Semantik . . . 30

5.4.2 Big-Step-Semantik . . . 31

5.5 Prozeduren . . . 33

5.5.1 Prozeduren ohne Parameter WhileP ROC . . . 33

5.5.2 Prozeduren mit einem Parameter WhileP ROCP . . . 34

5.6 Getypte VariablenWhileT . . . 38

5.6.1 Typen f¨urWhileT . . . 38

5.6.2 Ein Typsystem f¨urWhileT . . . 39

5.6.3 Small-Step-Semantik f¨urWhileT . . . 41

5.6.4 Typsicherheit von WhileT . . . 42

6 Denotationale Semantik 45 6.1 Denotationale Semantik . . . 45

6.2 Fixpunkttheorie . . . 50

6.3 Existenz des Fixpunkts f¨urwhile . . . 53

6.4 Bezug zur operationalen Semantik . . . 55

6.5 Continuation-style denotationale Semantik . . . 58

7 Axiomatische Semantik 63 7.1 Ein Korrektheitsbeweis mit der denotationalen Semantik . . . 63

(3)

7.4 Korrektheit der axiomatischen Semantik . . . 68

7.5 Vollst¨andigkeit der axiomatischen Semantik . . . 69

7.6 Semantische Pr¨adikate und syntaktische Bedingungen . . . 71

7.7 Verifikationsbedingungen . . . 72

(4)

Termine

Vorlesung 2-st¨undig Mi, 14 – 15.30h, SR 236, Informatik-Hauptgeb¨aude Ubung:¨ 2-st¨undig Di, 14 – 15.30h, SR 236, Informatik-Hauptgeb¨aude

Unterlagen

Vorlesung Webseite http://pp.info.uni-karlsruhe.de/lehre/SS2012/semantik/

Skript kapitelweise als PDF

Ubung¨ http://pp.info.uni-karlsruhe.de/lehre/SS2012/semantik/uebung.php Ubungsbl¨¨ atter:

• Ver¨offentlichung am Mittwoch nach der Vorlesung bzw. am Donnerstag

• Besprechung in der folgenden ¨Ubung

• Keine Abgabe und keine Korrektur

Anrechenbarkeit Diplom Informatik:

Vertiefungsgebiete

”Theoretische Grundlagen“ und

”Softwaretechnik und ¨Ubersetzerbau“

Master Informatik:

Module [IN4INSPT] Sprachtechnologien und [IN4INFM] Formale Methoden ECTS-Punkte: 4

Literatur

• Hanne Riis Nielson, Flemming Nielson: Semantics with Applications. An Appetizer.

Springer, 2007. ISBN: 978-1-84628-691-9.

Grundlage der meisten Themen der Vorlesung, sehr anschaulich und gut verst¨andlich

• John C. Reynolds: Theories of Programming Languages.

Cambridge University Press, 1998. ISBN: 0-521-59414-6.

Fokus auf denotationaler Semantik

• Benjamin C. Pierce: Types and Programming Languages.

MIT Press, 2002. ISBN: 0-262-162209-1.

Schwerpunkt auf dem Lamda-Kalk¨ul und Typsystemen, mit sehr guten Erkl¨arungen, auch zu weiterf¨uhrenden Themen.

• Glynn Winskel: The Formal Semantics of Programming Languages. An Introduction.

MIT Press, 1993. ISBN: 0-262-23169-7.

Ausf¨uhrlicher Beweis der Unentscheidbarkeit eines vollst¨andigen axiomatischen Kalk¨uls

(5)

1 Einf¨ uhrung

1.1 Was ist eine Semantik?

Syntax und Semantik sind zwei unabdingbare Bausteine der Beschreibung von (Programmier-)Sprachen:

Syntax k¨ummert sich darum, welche Zeichenfolgen g¨ultige S¨atze (Programme) der Sprache sind. Syntax umfasst also Vokabular (Schl¨usselw¨orter) und Grammatik. Semantik beschreibt, was die Bedeutung eines g¨ultigen Satzes (Programms) sein soll. F¨ur Programmiersprachen heißt das: Wie verh¨alt sich das Programm, wenn man es ausf¨uhrt?

Syntax legt auch den Aufbau eines Satzes, i. d. R. ein Baum, fest und erkl¨art wie man von einer Zeichenfolge zum Syntaxbaum kommt. Eine Semantik beschreibt, wie man dieser syntaktischen Struktur eine Bedeutung gibt, d.h.: Was ist die Bedeutung eines einzelnen Konstrukts? Wie erh¨alt man die Gesamtbedeutung aus den einzelnen Teilen?

Syntax und Semantik vieler Programmiersprachen sind standardisiert (C, C++, Pascal, Java, . . . ). F¨ur die Definition der Syntax werden formale Techniken routinem¨aßig in der Praxis eingesetzt: kontext- freie Grammatiken (EBNF). Das Verhalten von Konstrukten der Programmiersprache und deren Zusammenwirken beschreiben die meisten dieser Standards allerdings nur in nat¨urlicher Sprache, meistens auf englisch oder nur anhand konkreter Beispiele. F¨ur umfangreiche Programmiersprachen ist es auf diese Weise fast unm¨oglich, alle m¨oglichen Kombinationen eindeutig festzulegen und dabei trotzdem Widerspruchsfreiheit zu garantieren. Deswegen gibt es auch formale, d.h. mathematische, Beschreibungstechniken f¨ur Semantik, die das Thema dieser Vorlesung sind. Die funktionale Sprache ML wurde beispielsweise vollst¨andig durch eine formale Semantik definiert; auch f¨ur Java gibt es formale Modellierungen, die zwar nicht Teil der Sprachdefinition sind, aber den Entwurf und die Weiterentwicklungen wesentlich beeinflussten (z.B. Featherweight Java, Java light, Jinja).

1.2 Warum formale Semantik?

Die einfachste Definition einer Sprache ist mittels eines Compilers: Alle Programme, die der Compiler akzeptiert, sind syntaktisch korrekt; die Semantik ist die des Zielprogramms. Eine solche Definition ist aber sehr problematisch:

1. Keine Abstraktion. Um das Verhalten eines Programmes zu verstehen, muss man den Compiler und das Kompilat in der Zielsprache verstehen. F¨ur neue, abstrakte Konzepte in der Program- miersprache gibt es keine Garantie, dass die Abstraktionsschicht nicht durch andere Konstrukte durchbrochen werden kann – geht es doch, ist das eine der Hauptfehlerquellen bei der Entwicklung von Programmen.

Beispiele:

• Pointer-Arithmetik in C++ kann die Integrit¨at von Objekten zerst¨oren, weil damit beliebig (auch auf private) Felder zugegriffen werden kann.

• setjmp/longjmpin C widerspricht dem Paradigma, dass Methoden stack-artig aufgerufen werden.

• LATEX ist nur ein Aufsatz auf TEX, der zwar in vielen F¨allen eine gute Abstraktionsschicht schafft, aber diese nicht garantieren kann. Fast jeder ist schon ¨uber unverst¨andliche TEX- Fehlermeldungen und Inkompatibilit¨aten zwischen LATEX-Paketen gestoplert.

2. Plattformabh¨angigkeit und ¨Uberspezifikation. Ein Wechsel auf eine andere Zielsprache oder einen anderen Compiler ist fast unm¨oglich. Schließlich ist auch festgelegt, wie viele einzelne

(6)

Ausf¨uhrungsschritte (z. B. Anzahl der Prozessorzyklen) jedes einzelne Konstrukt genau ben¨otigen muss.

Zwischen

”Sprachdefinition“ und Implementierungsdetails des Compilers kann nicht unterschieden werden. Weiterentwicklungen aus der Compiler-Technik sind damit ausgeschlossen.

3. Bootstrapping. Auch ein Compiler ist nur durch seinen Programmtext definiert. Was ist aber die Semantik dieses Programmtextes?

Eine Semantikbeschreibung in Prosa wie bei den meisten Sprachstandards ist zwar besser, kann aber Mehrdeutigkeiten, Missverst¨andnisse oder Widerspr¨uche auch nicht verhindern. Demgegen¨uber stehen die Vorteile mathematischer Beschreibungen einer Semantik:

1. Vollst¨andige, rigorose Definition einer Sprache. Jedes syntaktisch g¨ultige Programm hat eine eindeutige, klar festgelegte Semantik. Mathematische Beschreibungen sind syntaktisch oft viel k¨urzer als englischer Fließtext. Programmierer k¨onnen die Semantik als Nachschlagereferenz verwenden, um subtile Feinheiten der Sprache zu verstehen. Compiler-Bauer k¨onnen die Semantik einer solchen Sprache als Korrektheitskriterium ihres Compilers verwenden. Damit verhalten sich Anwender-Programme gleich, unabh¨angig vom verwendeten (korrekten) Compiler.

2. Nachweis von Programmeigenschaften. Ohne formale Semantik als Grundlage lassen sich Eigen- schaften eines Programms nicht beweisen, ja nicht einmal mathematisch aufschreiben. Dabei unterscheidet man zwischen Eigenschaften, die alle Programme erf¨ullen und damit Meta-Eigen- schaften der Sprache bzw. Semantik sind (z. B. Typsicherheit), und solchen eines einzelnen Programms (z. B. Korrektheit eines Algorithmus).

3. Unterst¨utzung beim Programmiersprachenentwurf. Eine Programmiersprache mit vielen verschie- denen Konzepten, die klar, verst¨andlich und ohne unn¨otige Sonderf¨alle zusammenwirken, zu entwerfen, ist sehr schwierig. Bereits der Versuch, eine formale Semantik f¨ur eine Programmier- sprache zu entwerfen, deckt viele Inkonsistenzen und unerwartete Interaktionen auf.

Hat man eine formale Beschreibung der Semantik, l¨asst sich automatisch ein prototypischer Interpreter f¨ur die Sprache erzeugen, z. B. als Prolog-Programm. Dadurch k¨onnen verschiedene Designentscheidungen beim Entwurf der Semantik an konkreten Beispielen praktisch ausprobiert werden.

Programmverifikation ist einfacher, wenn die Semantik der Programmiersprache mathematisch einfach und klar ist. Eine zuf¨allig, nach Gutd¨unken entworfene Programmiersprache hat in der Regel ein sehr kompliziertes mathematisches Modell. Dementsprechend ist es auch schwierig, dar¨uber Beweise zu f¨uhren, da stets viele Sonderf¨alle ber¨ucksichtigt werden m¨ussen.

4. Klare und konsistente Begrifflichkeit. Formale Semantik arbeitet mit der Sprache und den Begriffen der Mathematik, ¨uber deren Bedeutung man sich im Klaren ist. Damit werden Mehrdeutigkeiten und Missverst¨andnisse von vornherein ausgeschlossen.

Beispiele:

• Was ist der Wert vonxam Ende?

b = true; c = false;

if (b) if (c) x = 1; else x = 2;

• Was ist der Wert vonxbzw. i nach Ausf¨uhrung des folgenden C-Fragments? Was w¨are er in Java?

(7)

int i = 1;

i += i++ + ++i;

• Sind die beiden Initialisierungen vonb¨aquivalent?

boolean f(int a, int b) { return (a == 0) && (b == 0);

}

boolean b = (1 == 0) && (2 / 0 == 0);

boolean b = f(1, 2 / 0);

1.3 Operational, denotational und axiomatisch

In dieser Vorlesung werden die drei bekanntesten Beschreibungsarten f¨ur Semantiken vorgestellt – mit einem Schwerpunkt auf operationaler Semantik:

Operational Die Bedeutung eines Konstrukts ergibt sich aus seinen (abstrakten) Ausf¨uhrungsschrit- ten, die durch symbolische Regeln beschrieben werden. Neben dem Ergebnis der Berechnung wird auch modelliert, wie die Berechnung zum Ergebnis kommt. Die Regeln beschreiben dabei nur eine m¨ogliche (idealisierte) Implementierung der Sprache, reale Implementierungen k¨onnen andere, ¨aquivalente Abl¨aufe verwenden.

Denotational Jedes Konstrukt wird als mathematisches Objekt realisiert, welches nur den Effekt seiner Ausf¨uhrung modelliert. Im Gegensatz zur operationalen Semantik ist irrelevant, wie der Effekt zustande kommt.

Axiomatisch Die Bedeutung eines Programms wird indirekt festgelegt, indem beschrieben wird, welche Eigenschaften des Programms (in einem zu entwerfenden Logik-Kalk¨ul) beweisbar sind.

Die drei verschiedenen Ans¨atze erg¨anzen sich: F¨ur Compiler und Implementierungen sind operationale Semantiken gut geeignet. Denotationale Konzepte finden sich oft in der Programmanalyse. Programm- verifikation st¨utzt sich auf die axiomatische Semantik. Zu jedem Ansatz werden wir eine Semantik f¨ur eine einfache imperative Sprache – ggf. mit verschiedenen Spracherweiterungen – entwickeln und die Beziehung der verschiedenen Semantiken zueinander untersuchen.

Beispiel 1. Semantik des Programms z := x; x := y; y := z

1. Die operationale Semantik beschreibt die Semantik, indem sie definiert, wie das Programm auszuf¨uhren ist: Eine Sequenz von zwei durch ; getrennten Anweisungen f¨uhrt die einzelnen Anweisungen nacheinander aus. Eine Zuweisung der Form < V ariable > := < Ausdruck >

wertet zuerst den Ausdruck zu einem Wert aus und weist diesen Wert dann der Variablen zu.

F¨ur einen Zustand [x7→5,y7→7,z7→0], der den Variablenx,yundzdie Werte 5, 7 und 0 zuweist, ergibt sich folgende Auswertungssequenz:

hz := x; x := y; y := z, [x7→5,y7→7,z7→0]i

1 hx := y; y := z, [x7→5,y7→7,z7→5]i

1 hy := z, [x7→7,y7→7,z7→5]i

1 [x7→7,y7→5,z7→5]

(8)

2. Die denotationale Semantik k¨ummert sich nur um den Effekt der Ausf¨uhrung, nicht um die einzelnen Berechnungsschritte. Entsprechend ist die Semantik eines solchen Programms eine Funktion, die einen Ausgangszustand in einen Endzustand ¨uberf¨uhrt. F¨ur eine Sequenz erh¨alt man die Funktion durch Komposition (Hintereinanderausf¨uhrung) der Funktionen der beiden Anweisungen. Die Bedeutung einer Zuweisung ist die Funktion, die den ¨ubergebenen Zustand so

¨andert, dass der Variablen dann der Wert des Ausdrucks zugewiesen ist.

F¨ur das Programm ergibt sich dann:

DJz := x; x := y; y := zK(σ) = (DJy := zK◦ DJx := yK◦ DJz := xK) (σ)

=DJy := zK(DJx := yK(DJz := xK(σ)))

=DJy := zK(DJx := yK(σ[z7→σ(x)]))

=DJy := zK(σ[z7→σ(x), x7→σ[z7→σ(x)](y)])

=DJy := zK(σ[z7→σ(x), x7→σ(y)])

=σ[z7→σ(x), x7→σ(y), y7→σ[z7→σ(x), y7→σ(y)](z)]

=σ[x7→σ(y), y7→σ(x), z7→σ(x)]

F¨urσ = [x7→5,y7→7,z7→0] ergibt dies wieder:

DJz := x; x := y; y := zK(σ) = [x7→7,y7→5,z7→5]

3. Axiomatische Semantik konzentriert sich auf die Korrektheit eines Programms bez¨uglich Vor- und Nachbedingungen. Immer, wenn ein Startzustand die Vorbedingung erf¨ullt, dann sollte – sofern das Programm terminiert – nach der Ausf¨uhrung des Programms mit diesem Startzustand der Endzustand die Nachbedingung erf¨ullen.

{x=n∧y=m}z := x; x := y; y := z{x=m∧y=n}

Dabei ist x = n ∧y = m die Vorbedingung und x = m∧y = n die Nachbedingung. Die Hilfsvariablen (logical variables)nund m, die nicht im Programm vorkommen, merken sich die Anfangswerte vonxund y.

Eine axiomatische Semantik definiert ein Regelsystem, mit dem Aussagen wie obige hergeleitet werden k¨onnen. Beispielsweise ist {P}c1; c2{Q} f¨ur eine Sequenz c1; c2 herleitbar, wenn {P}c1{R} und{R}c2{Q}f¨ur eine BedingungR herleitbar sind. Dadurch ergeben sich viele Bedingungen an das Programmverhalten, die dieses dadurch (m¨oglichst vollst¨andig) beschreiben.

Wichtig dabei ist, dass die Regeln korrekt sind, d.h, keine widerspr¨uchlichen Bedingungen herleitbar sind. Umgekehrt sollen sich m¨oglichst alle Eigenschaften eines Programms durch das Kalk¨ul herleiten lassen (Vollst¨andigkeit).

(9)

2 Die Sprache While

Whileist eine einfache, imperative Programmiersprache, f¨ur die in dieser Vorlesung in allen drei Ans¨atzen eine Semantik ausgearbeitet wird. Obwohl eine Semantik erst auf einem abstrakten Syntaxbaum aufbaut, muss man sich auf eine konkrete Syntax festlegen, um ¨uberhaupt Programme textuell aufschreiben zu k¨onnen.

2.1 Syntax

Programme werden ¨ublicherweisein Schreibmaschinenschriftdargestellt. Deren Syntax wird durch eine BNF-Grammatik mit drei syntaktischen Kategorien beschrieben: arithmetische Ausdr¨ucke Aexp, boolesche Ausdr¨uckeBexpund AnweisungenCom. Außerdem braucht man noch numerische LiteraleNum und einen unendlichen Vorrat Varan (Programm-)Variablen. Die Darstellung der numerischen Literale und (Programm-)Variablen ist nicht weiter relevant, im Folgenden werden die Dezimaldarstellung (z.B.

120,5) bzw. einfache Zeichenketten wie x,catch22 verwendet.

Variablenkonvention: Um nicht st¨andig die syntaktische Kategorie einer (Meta-)Variable angeben zu m¨ussen, bezeichne astets einen arithmetischen Ausdruck,b einen booleschen,ceine Anweisung, nein numerisches Literal undx eine Programmvariable ausVar – entsprechende Dekorationen mit Indizes, Strichen, usw. eingeschlossen. Dabei muss man zwischen einer Meta-Variablenx, die f¨ur eine beliebige, aber feste Programmvariable ausVar steht, und den konkreten Programmvariablen wie x,y selbst unterscheiden.

Definition 1 (Syntax von While). Die Syntax von Ausdr¨ucken und Anweisungen sei durch folgende kontext-freie BNF-Grammatik gegeben:

Aexp a ::= n|x |a1 - a2 |a1 * a2

Bexp b ::= true|a1 <= a2 |not b |b1 && b2

Com c ::= skip|x := a|c1; c2 |if (b) then c1 else c2 |while (b) do c

Obwohl diese Sprache minimalistisch ist, sind viele weitere Programmkonstrukte ausdr¨uckbar: Bei- spielsweise sinda1 + a2,a1 == a2,false undb1 || b2 nur syntaktischer Zucker f¨ur

a1 - (0 - a2), (a1 <= a2) && (a2 <= a1), not true und not ((not b1) && (not b2))

Durch diese Reduktion auf das Wesentliche wird es einfacher, eine Semantik anzugeben und Beweise zu f¨uhren, da weniger F¨alle ber¨ucksichtigt werden m¨ussen.

Obige Grammatik ist mehrdeutig, z. B. hatwhile (true) do skip; x := yzwei verschiedene Ablei- tungsb¨aume, d.h. zwei verschiedene Syntaxb¨aume. Da die Semantik aber erst auf dem Syntaxbaum aufbaut, ist das nicht wesentlich: Man kann immer mittels zus¨atzlicher Klammern den gew¨unschten Baum eindeutig beschreiben.

2.2 Zustand

Whileenth¨alt Zuweisungen an (Programm-)Variablen x := aund Zugriff auf Variablen in arithme- tischen Ausdr¨ucken. EinZustand modelliert den Speicher f¨ur diese Variablen, der sich w¨ahrend der Ausf¨uhrung eines Programms von einem Anfangszustand in einen Endzustand entwickelt. F¨ur das

(10)

formale Modell ist ein Zustand, hier ¨ublicherweise mitσ bezeichnet, eine Abbildung vonVarnach Z, die jeder Variablenxeinen Wert σ(x) zuordnet. Die Menge aller dieser Zust¨ande sei Σ.

Ein realer Computer muss nat¨urlich viele weitere Informationen im Zustand speichern, die nicht in einem (abstrakten) Zustand aus Σ enthalten sind, z.B. die Zuordnung von Variablen zu Speicheradressen.

Diese weiteren Informationen sind aber f¨ur die Beschreibung des Verhaltens von Whilenicht relevant, der abstrakte Zustand und das Modell abstrahieren also davon.

2.3 Semantik von Ausdr¨ucken

Ausdr¨ucke inWhile liefern einen Wert (Zahl oder Wahrheitswert) zur¨uck, ver¨andern aber den Zustand nicht. Da sie Variablen enthalten k¨onnen, wird der Wert erst durch einen Zustand endg¨ultig festgelegt.

F¨ur eine Zahl nin Programmdarstellung, in unserem Fall Dezimaldarstellung, liefere NJnKden Wert der Zahl als Element vonZ. Beispiel: N J123K= 123, wobei 123∈Aexpein arithmetischer Ausdruck und 123∈Zeine ganze Zahl ist.

Definition 2 (Semantik arithmetischer Ausdr¨ucke). F¨ur beliebige arithmetische Ausdr¨ucke a definiertAJaKσ rekursiv ¨uber den Syntaxbaum den Wert vona im Zustandσ:

AJnKσ = NJnK AJxKσ = σ(x)

AJa1 - a2Kσ = AJa1Kσ− AJa2Kσ AJa1 * a2Kσ = AJa1Kσ· AJa2

AJ Kist also eine Funktion des TypsAexp⇒Σ⇒Z, definiert ¨uber strukturelle (primitive) Rekursion

¨uber den Syntaxbaum arithmetischer Ausdr¨ucke.

Beispiel 2. Was istAJa1 + a2Kσ?

a1 + a2 ist syntaktischer Zucker f¨ura1 - (0 - a2). Damit gilt:

AJa1 + a2Kσ =AJa1 - (0 - a2)Kσ=AJa1Kσ− AJ0 - a2Kσ=AJa1Kσ−(AJ0Kσ− AJa2Kσ)

=AJa1Kσ−(0− AJa2Kσ) =AJa1Kσ+AJa2Kσ Die syntaktische Abk¨urzung a1 + a2 ist also sinnvoll.

Analog zu arithmetischen Ausdr¨ucken l¨asst sich der Wert von booleschen Ausdr¨ucken definieren. Dabei bezeichnentt undff die beiden Wahrheitswerte inB.

Definition 3 (Semantik boolescher Ausdr¨ucke).

Die Semantik boolescher Ausdr¨ucke BJ K ist definiert durch:

BJtrueKσ = tt

BJa1 <= a2Kσ = AJa1Kσ ≤ AJa2Kσ BJnot bKσ = ¬BJbKσ

BJb1 && b2Kσ = BJb1Kσ∧ BJb2

Ubung:¨ Was istBJa1 == a2Kσ? Ist die Abk¨urzung sinnvoll? Was w¨are, wenn auch Ausdr¨ucke den Zustand ¨andern k¨onnten?

(11)

3 Operationale Semantik f¨ ur While

Eine operationale Semantik f¨urWhile beschreibt nicht nur das Ergebnis einer Programmausf¨uhrung, sondern auch, wie man zu diesem Ergebnis gelangen kann. Daf¨ur gibt es zwei Modellierungsans¨atze:

Big-step Semantik (Auswertungssemantik, natural semantics): Hier wird beschrieben, wie man aus dem Verhalten der Teile eines Programmkonstrukts dessen Gesamtverhalten konstruiert.

Small-step Semantik (Transitionssemantik, structural operational semantics): Hier liegt der Fokus auf einzelnen, kleinen Berechnungsschritten, die nach vielen Schritten zum Ende der Programm- ausf¨uhrung gelangen.

3.1 Big-Step-Semantik f¨ur While

Eine Big-Step Semantik ist eine Auswertungsrelationhc, σi ⇓σ0, die f¨ur ein Programm cund einen Anfangszustandσ bestimmt, obσ0 ein m¨oglicher Endzustand einer Ausf¨uhrung vonc inσ ist.

Definition 4 (Big-Step-Semantik).

Die Auswertungsrelation hc, σi ⇓σ0 wird durch folgende Regeln induktiv definiert:

SkipBS:hskip, σi ⇓σ AssBS:hx := a, σi ⇓σ[x7→ AJaKσ]

SeqBS: hc0, σi ⇓σ0 c1, σ0

⇓σ00 hc0; c1, σi ⇓σ00

IfTTBS: BJbKσ =tt hc0, σi ⇓σ0

hif (b) then c0 else c1, σi ⇓σ0 IfFFBS: BJbKσ =ff hc1, σi ⇓σ0 hif (b) then c0 else c1, σi ⇓σ0

WhileFFBS: BJbKσ =ff hwhile (b) do c, σi ⇓σ

WhileTTBS: BJbKσ=tt hc, σi ⇓σ0

while (b) do c, σ0

⇓σ00 hwhile (b) do c, σi ⇓σ00

Formal isth , i ⇓ die kleinste Menge ¨uberCom×Σ×Σ, die unter obigen Regeln abgeschlossen ist.

Damit ergibt sich auch folgende Induktionsregel f¨urh , i ⇓ :

hc, σi ⇓σ0 ∀σ. P(skip, σ, σ) ∀x, a, σ. P(x := a, σ, σ[x7→ AJaKσ])

∀c0, c1, σ, σ0, σ00. hc0, σi ⇓σ0∧ c1, σ0

⇓σ00∧P(c0, σ, σ0)∧P(c1, σ0, σ00)−→P(c0; c1, σ, σ00)

∀b, c0, c1, σ, σ0.BJbKσ =tt∧ hc0, σi ⇓σ0∧P(c0, σ, σ0)−→P(if (b) then c0 else c1, σ, σ0)

∀b, c0, c1, σ, σ0.BJbKσ =ff∧ hc1, σi ⇓σ0∧P(c1, σ, σ0)−→P(if (b) then c0 else c1, σ, σ0)

∀b, c, σ. BJbKσ=ff−→P(while (b) do c, σ, σ)

∀b, c, σ, σ0, σ00.BJbKσ=tt∧ hc, σi ⇓σ0

while (b) do c, σ0

⇓σ00

P(c, σ, σ0)∧P(while (b) do c, σ0, σ00)−→P(while (b) do c, σ, σ00) P(c, σ, σ0)

(12)

Beispiel 3.

Semantik des Programms z := x; (x := y; y := z) im Zustand σ0 = ε[x7→5,y7→7,z7→0] als Ableitungsbaum:

hz := x, σ0i ⇓σ1 AssBS

hx := y, σ1i ⇓σ2 AssBS hy := z, σ2i ⇓σ3 AssBS hx := y; y := z, σ1i ⇓σ3 SeqBS hz := x; (x := y; y := z), σ0i ⇓σ3 SeqBS wobei σ10[z7→5], σ21[x7→7] undσ32[y7→5], also σ3 =ε[x7→7,y7→5,z7→5].

Ubung:¨ Was ist der Ableitungsbaum von folgendem Programm f¨ur den Anfangszustand σ0 =ε[x7→13, y7→5, z7→9]?

z := 0; while (y <= x) do (z := z + 1; x := x - y) Lemma 1 (Schleifenabwicklungslemma).

while (b) do c hat das gleiche Verhalten wieif (b) then (c; while (b) do c) else skip.

Beweis. Seiw=while (b) do cund w0 =if (b) then c; while (b) do c else skip. Zu zeigen:

hw, σi ⇓σ0 gilt genau dann, wennhw0, σi ⇓σ0. Beweis: Fallunterscheidung nach BJbKσ:

• FallBJbKσ =ff: Nach den Regeln der Big-Step-Semantik l¨asst sichhw, σi ⇓σ0 nur mit der Regel WhileFFBS ableiten (Regelinversion);hw0, σi ⇓σ0 nur mit den Regeln IfFFBS undSkipBS. Also:

BJbKσ=ff σ =σ0 hw, σi ⇓σ0

BJbKσ=ff σ=σ0 hskip, σi ⇓σ0 w0, σ

⇓σ0

• FallBJbKσ =tt: Wieder mit Regelinversion gibt es nur die RegelWhileTTBS f¨urhw, σi ⇓σ0 und IfTTBS undSeqBS f¨urhw0, σi ⇓σ0. Also:

BJbKσ=tt A hc, σi ⇓σ

B hw, σi ⇓σ0

hw, σi ⇓σ0

BJbKσ =tt

A hc, σi ⇓σ

B hw, σi ⇓σ0 hc; w, σi ⇓σ0 w0, σ

⇓σ0

3.2 Determinismus der Big-Step-Semantik

Eine Semantik istdeterministisch, wenn sie jedem Programm und jedem Anfangszustand maximal ein Verhalten zuordnet. F¨ur eine Big-Step-Semantik heißt dies konkret, dass dann auch die Endzust¨ande gleich sind.

Theorem 2 (Determinismus). h , i ⇓ ist deterministisch.

Beweis. Zu zeigen: Falls hc, σ0i ⇓σ1 undhc, σ0i ⇓σ2, dann giltσ12.

Beweis: Induktion nachhc, σ0i ⇓σ12 beliebig). Damit P(c, σ0, σ1)≡ ∀σ2. hc, σ0i ⇓σ2 −→σ12.

• FallSkipBS: Zu zeigen: F¨ur alle σ giltP(skip, σ, σ), d.h.∀σ2. hskip, σi ⇓σ2 −→σ=σ2.

Sei alsoσ2 beliebig mit hskip, σi ⇓σ2. Aus den Regeln der Big-Step-Semantik l¨asst sich dies nur mit der RegelSkipBS ableiten (Regelinversion). Damit folgt σ2 =σ.

(13)

• FallAssBS: Zu zeigen: F¨ur alle x,aund σ giltP(x := a, σ, σ[x7→ AJaKσ]), d.h.

∀σ2. hx := a, σi ⇓σ2 −→σ[x7→ AJaKσ] =σ2

Sei alsoσ2 beliebig mithx := a, σi ⇓σ2. Durch Regelinversion (AssBS) folgtσ2=σ[x7→ AJaKσ].

• FallSeqBS: Zu zeigen: F¨ur alle c0,c1, σ, σ0 und σ00 mit hc0, σi ⇓ σ0 und hc1, σ0i ⇓ σ00 gilt: Aus P(c0, σ, σ0) und P(c1, σ0, σ00) folgt P(c0; c1, σ, σ00), d.h.:

∀σ2. hc0, σi ⇓σ2 −→σ02

∧ ∀σ2. c1, σ0

⇓σ2 −→σ002

−→ ∀σ2. hc0; c1, σi ⇓σ2 −→σ002

Sei also σ2 beliebig mit hc0; c1, σi ⇓ σ2. Mit Regelinversion (SeqBS) gibt es ein σ, so dass hc0, σi ⇓σ undhc1, σi ⇓σ2. Nach InduktionsannahmeP(c0, σ, σ0) folgt aushc0, σi ⇓σ, dass σ0 = σ. Damit gilt auch hc1, σ0i ⇓ σ2 und mit der Induktionsannahme P(c1, σ0, σ00) folgt die Behauptung σ002.

• FallIfTTBS: Zu zeigen: F¨ur alle b, c0, c1, σ und σ0 mit BJbKσ = tt und hc0, σi ⇓ σ0 gilt: Aus P(c0, σ, σ0) folgt P(if (b) then c0 else c1, σ, σ0).

Sei also σ2 beliebig mit hif (b) then c0 else c1, σi ⇓ σ2, was nur durch die Regeln IfTTBS und IfFFBS ableitbar sein k¨onnte. WegenBJbKσ =ttist IfFFBS ausgeschlossen. Damit folgt dass hc0, σi ⇓σ2 und mit der InduktionsannahmeP(c0, σ, σ0) die Behauptung σ02.

• FallIfFFBS: Analog zuIfTTBS.

• FallWhileTTBS:

Zu zeigen: F¨ur alleb,c,σ,σ0 undσ00 mit BJbKσ =tt,hc, σi ⇓σ0 undhwhile (b) do c, σ0i ⇓σ00 gilt: Aus P(c, σ, σ0) und P(while (b) do c, σ0, σ00) folgt P(while (b) do c, σ, σ00).

Sei also σ2 beliebig mit hwhile (b) do c, σi ⇓σ2. Mit Regelinversion (WhileTTBS,BJbKσ =tt schließt WhileFFBS aus) gibt es ein σ, so dass hc, σi ⇓ σ und hwhile (b) do c, σi ⇓ σ2. Aus hc, σi ⇓ σ folgt mit der Induktionsannahme P(c, σ, σ0), dass σ0 = σ. Damit folgt mit der Induktionsannahme P(while (b) do c, σ0, σ00) aus hwhile (b) do c, σi ⇓ σ2 die Behauptung, dass σ002.

• FallWhileFFBS: Zu zeigen: F¨ur alle b,c und σ mitBJbKσ=ffgiltP(while (b) do c, σ, σ).

Sei alsoσ2 beliebig mithwhile (b) do c, σi ⇓σ00. Nach Regelinversion (WhileFFBS,BJbKσ=ff schließt WhileTTBS aus) folgt die Behauptung σ=σ2.

3.3 Small-Step-Semantik f¨ur While

Kern einer Small-Step-Semantik ist eine Ein-Schritt-Auswertungsrelationhc, σi →1 hc0, σ0i, die f¨ur ein Programmcund Zustand σ einen einzelnen Rechenschritt beschreibt: c0 ist der Rest des Programms, der noch im neuen Zustand σ0 auszuf¨uhren verbleibt.

Definition 5 (Small-Step-Semantik f¨ur While). Die Ein-Schritt-Auswertungsrelation →1 der Small-Step-Semantik ist induktiv ¨uber den Syntaxbaum definiert durch

(14)

AssSS:hx := a, σi →1 hskip, σ[x7→ AJaKσ]i Seq1SS: hc0, σi →1 hc00, σ0i

hc0; c1, σi →1 hc00; c1, σ0i Seq2SS:hskip; c, σi →1hc, σi

IfTTSS: BJbKσ=tt

hif (b) then c0 else c1, σi →1 hc0, σi IfFFSS: BJbKσ=ff

hif (b) then c0 else c1, σi →1 hc1, σi

WhileSS:hwhile (b) do c, σi →1 hif (b) then c; while (b) do c else skip, σi Definition 6 (blockiert).

Eine Konfiguration, die nicht weiter auswerten kann, istblockiert, notiert als hc, σi 6→1.

F¨ur die Anweisungskipgibt es keine Auswertungsregel:hskip, σibezeichnet eine Endkonfiguration des Programms,σist der Endzustand. Kennzeichen einer guten Semantik ist, dass von allen (wohlgeformten) Konfigurationen nur Endkonfigurationen blockiert sind.

Definition 7 (Ableitungsfolge). EineAbleitungsfolge f¨ur γ0 =hc, σi ist eine (endliche oder unend- liche) Folge (γi)i mitγ01γ11 γ21 . . .. Sie istmaximal, falls (γi)i unendlich ist oder das letzte γk keine Reduktion in →1 besitzt. γ →n1 γ0 (γ → 1 γ0) bezeichne, dass es eine Ableitungsfolge mit n (endlich vielen) Schritten von γ nachγ0 gibt.→ 1 ist die reflexive, transitive H¨ulle von →1.

Maximale Ableitungsfolgen beschreiben das Programmverhalten. Nichtterminierende Ausf¨uhrungen entsprechen unendlichen Ableitungsfolgen – diese habenkeinen Endzustand; γ→1 bezeichne, dass es eine unendlich lange Ableitungsfolge gibt, die inγ beginnt.

Beispiel 4. Semantik des Programmsz := x; (x := y; y := z)im Zustandσ0 =ε[x7→5,y7→7,z7→0]

als maximale Ableitungsfolge:

hz := x; (x := y; y := z), σ0i →1hskip; (x := y; y := z), σ1i

1hx := y; y := z, σ1i →1hskip; y := z, σ2i →1 hy := z, σ2i →1 hskip, σ3i

wobeiσ10[z7→5],σ21[x7→7] undσ32[y7→5], alsoσ3=ε[x7→7,y7→5,z7→5]. Jeder einzelne Schritt muss dabei durch einen Ableitungsbaum f¨ur→1 gerechtfertigt werden, z. B.:

hz := x, σ0i →1 hskip, σ1i AssSS

hz := x; (x := y; y := z), σ0i →1 hskip; (x := y; y := z), σ1i Seq1SS Beispiel 5 (Nichttermination).

Seiw=while (not (x == 1)) do x := x + 1undσn= [x7→n]. F¨urhw, σ0i ergibt sich folgende maximale (endiche) Ableitungsfolge:

hw, σ0i →1h

=if

z }| {

if (not (x == 1)) then x := x + 1; w else skip, σ0i

1hx := x + 1; w, σ0i →1 hskip; w, σ1i →1 hw, σ1i →1hif, σ1i →1hskip, σ1i

(15)

F¨urhw, σ2i ist die maximale Ableitungsfolge1 unendlich:

hw, σ2i →1 hif, σ2i →1 hx := x + 1; w, σ2i →1hskip; w, σ3i

1hw, σ3i →1 hif, σ3i →1 hx := x + 1; w, σ3i →1hskip; w, σ4i

1hw, σ4i →1 . . .

H¨aufig beschreiben die einzelnen Schritte maximaler Ableitungsfolgen zu detailliert, was ein Programm berechnet. Beispielsweise haben die Programm skip; skip und skip unterschiedliche maximale Ableitungsfolgen und damit eine unterschiedliche Semantik. Deswegen abstrahiert man ¨ublicherweise von den maximalen Ableitungsfolgen und nimmt die transitive H¨ulle →1 zu einer Endkonfiguration beziehungsweise→1 als Semantik eines Programms.

Formal gesehen sind→ 1 und →n1 ganz unterschiedlich definiert. Es gilt aber hc, σi→1 hc0, σ0i gdw. ∃n. hc, σi→n1 hc0, σ0i

Deswegen werden wir im Folgenden bei Bedarf von der→1 auf→n1 und wieder zur¨uck wechseln – unter Beachtung, dass nexistenziell quantifiziert ist.

Lemma 3 (Fortschritt). skip ist das einzige Programm, das blockiert ist.

Beweis. Zu zeigen: F¨ur alle Programme c außer skip und jeden Zustand σ gibt es c0 und σ0 mit hc, σi →1 hc0, σ0i. Beweis mittels Induktion ¨uberc:

• Fallc=skip: Explizit ausgeschlossen.

• F¨allec=x := a,c=if (b) then c1 else c2 und c=while (b) do c0:

Folgen direkt aus den RegelnAssSS,IfTTSS, IfFFSS (Fallunterscheidung nachBJbKσ) undWhileSS.

• Fallc=c1; c2: Induktionshypothesen:

(i) Falls c1 6=skip, dann gibt es c01 undσ01 mithc1, σi →1hc01, σ01i.

(ii) Fallsc2 6=skip, dann gibt es c02 undσ02 mithc2, σi →1hc02, σ02i.

Zu zeigen: Es gibt c0 und σ0 mithc1; c2, σi →1 hc0, σ0i.

Fallunterscheidung nachc1 =skip:

– Fallc1 =skip: Folgt direkt aus RegelSeq2SS

– Fallc1 6=skip: Mit Induktionshypothese (i) gibt es c01 und σ01 mit hc1, σi →1 hc01, σ01i. Mit Regel Seq1SS folgt hc1; c2, σi →1 hc01; c2, σ10i.

Im Progress-Beweis wurden alle Regeln f¨ur→1 benutzt, keine ist also ¨uberfl¨ussig.

Theorem 4 (Determinismus). h , i →1h , i ist deterministisch.

Beweis analog zum Determinismus f¨ur die Big-Step-Semantikh , i ⇓ (Thm. 2).

Korollar 5. F¨ur alle c undσ gibt es genau eine maximale Ableitungsfolge.

Die Existenz einer maximalen Ableitungsfolge folgt aus der Existenz unendlich langer Folgen, die Eindeutigkeit aus dem Determinismus durch Induktion.

1urWhilesind maximale Ableitungsfolgen eindeutig, s. Kor. 5 unten

(16)

3.4 Aquivalenz zwischen Big-Step- und Small-Step-Semantik¨

Big-Step- und Small-Step-Semantik sind zwei Semantik-Definitionen f¨ur While. Bei der Big-Step- Semantik interessiert nur der Endzustand einer Programmausf¨uhrung, w¨ahrend eine Ableitungsfolge in der Small-Step-Semantik zus¨atzlich alle einzelnen Zwischenberechnungsschritte und -zust¨ande enth¨alt.

Trotzdem passen beide Definitionen wie folgt zusammen, was in diesem Abschnitt bewiesen wird:

hc, σi ⇓σ0 genau dann, wennhc, σi→1 hskip, σ0i

Die ¨Aquivalenzbeweise ben¨otigen die beiden folgenden Lemmas f¨ur Sequenz. G¨abe es mehr Sprachkon- strukte mit einer rekursiven Regel f¨ur die Small-Step-Semantik wieSeq1SS, br¨auchte man entsprechende Lemmas f¨ur jedes dieser.

Lemma 6 (Liftinglemma f¨ur Sequenz). Falls hc, σi→n1hc0, σ0i, dannhc; c2, σi→n1hc0; c2, σ0i.

Beweis. Induktion ¨ubern, der Induktionsschritt folgt aus der RegelSeq1SS.

Lemma 7 (Zerlegungslemma f¨ur Sequenz). Wenn hc1; c2, σi→n1hskip, σ00i, dann gibt esi,j undσ0, so dasshc1, σi→i 1hskip, σ0i und hc2, σ0i→j 1 hskip, σ00i miti+j+ 1 =n.

Beweis. Beweis per Induktion ¨uber n(c1 und σ beliebig):

• Basisfall n= 0: Dieser Fall ist unm¨oglich, weil c1; c2 6=skip.

• Induktionsschritt n+ 1: Induktionsannahme: F¨ur allec1undσgilt: Wennhc1; c2, σi→n1hskip, σ00i, dann gibt es i,j und σ0 mithc1, σi→i 1hskip, σ0i,hc2, σ0i→j 1hskip, σ00iund i+j+ 1 =n.

Unter der Annahme hc1; c2, σin+11 hskip, σ00i ist zu zeigen, dass esi,j und σ0 gibt mit hc1, σi→i 1hskip, σ0i,hc2, σ0i→j 1 hskip, σ00i undi+j+ 1 =n+ 1.

Beweis: Wegen hc1; c2, σin+11 hskip, σ00igibt es ein cund σ, so dass hc1; c2, σi →1 hc, σi→n1hskip, σ00i.

Mit Regelinversion folgt aus hc1; c2, σi →1 hc, σi, dass entweder (Seq2SS) c1 = skip, c = c2, σ = σ oder (Seq1SS) c von der Form c01; c2 mit hc1, σi →1 hc01, σi ist. Im ersten Fall folgt die Behauptung mit der Aufteilung i = 0, j = n und σ0 = σ. Im anderen Fall ergibt die Induktionsannahme f¨urhc01; c2, σi→n1 hskip, σ00ieine Aufteilung inhc01, σi→i01 hskip, σ0i und hc2, σ0i j

0

1 hskip, σ00imiti0+j0+ 1 =n. Mithc1, σi →1hc01, σiergibt sich dann die Behauptung f¨uri=i0+ 1, j=j0 undσ00.

Theorem 8 (Small-Step simuliert Big-Step). Aushc, σi ⇓σ0 folgt hc, σi→1 hskip, σ0i.

Beweis in der ¨Ubung.

Theorem 9 (Big-Step simuliert Small-Step). Aushc, σi→1 hskip, σ0ifolgt hc, σi ⇓σ0. Beweis. Wegen hc, σi →1 hskip, σ0i gibt es ein nmit hc, σi →n1 hskip, σ0i. Beweis von hc, σi ⇓σ0 pervollst¨andiger Induktion uber¨ n(c,σ,σ0 beliebig):

Sein beliebig. Induktionsannahme: F¨ur allem < n undc,σ, σ0 gilt: Wenn hc, σi→m1hskip, σ0i, dann auchhc, σi ⇓σ0. Zu zeigen: Aus (i)hc, σi→n1hskip, σ0i folgthc, σi ⇓σ0 f¨ur beliebigec,σ undσ0. Fallunterscheidung nachc:

• Fallc=skip: Mit (i) folgt, dassn= 0 und σ0 =σ.hskip, σi ⇓σ folgt aus Regel SkipBS.

(17)

• Fallc=x := a: Mit (i) folgt, dass n = 1 und σ0 = σ[x7→ AJaKσ]. hx := a, σi ⇓ σ[x7→ AJaKσ]

folgt aus der Regel AssBS.

• Fallc=c1; c2:

Nach dem Zerlegungslemma l¨asst sich (i) inhc1, σi→i 1hskip, σi undhc2, σi→j 1 hskip, σ0i mit i+j+ 1 =naufteilen. Damit ist insbesondere i < n undj < n, d.h., die Induktionsannahme l¨asst sich auf beide Teile anwenden: hc1, σi ⇓σ und hc2, σi ⇓ σ0. Daraus folgt die Behauptung mit der RegelSeqBS.

• Fallc=if (b) then c1 else c2: Aus (i) folgt mit Regelinversion, dass n > 0 und entweder (IfTTSS) BJbKσ = tt und hc1, σi n−11 hskip, σ0i oder (IfFFSS) BJbKσ = ff und hc2, σi n−11 hskip, σ0i. In beiden F¨allen l¨asst sich die Induktionsannahme anwenden und die Behauptung folgt aus den RegelnIfTTBS bzw. IfFFBS.

• Fallc=while (b) do c: Aus (i) folgt mit Regelinversion (WhileSS), dassn >0 und hwhile (b) do c, σi →1 hif (b) then c; while (b) do c else skip

| {z }

=w0

, σin−11 hskip, σ0i.

Wendet man die Induktionshypothese mit m = n−1 < n und c = w0 an, so folgt hw0, σi ⇓ σ0. Da w0 nach dem Schleifenabwicklungslemma (Lem. 1) in der Big-Step-Semantik ¨aquivalent zu while (b) do c ist, gilt auchhwhile (b) do c, σi ⇓σ0.

Korollar 10 ( ¨Aquivalenz von Big-Step- und Small-Step-Semantik).

F¨ur alle c,σ und σ0 gilthc, σi ⇓σ0 genau dann, wennhc, σi→ 1hskip, σ0i gilt.

3.5 Aquivalenz von Programmen¨

Zu entscheiden. ob zwei Programme ¨aquivalent sind, ist ein wesentlicher Anwendungsbereich f¨ur Semantiken. Die bisherigen ¨Aquivalenzbegriffe sind daf¨ur aber i. d. R. zu feingranular, wie folgendes Beispiel zeigt:

tmp := y; y := x; x := tmp x := x - y; y := y + x; x := y - x

Beide Programme vertauschen die Inhalte vonxundy, aber das erste verwendet dazu die Hilfsvariable tmp. Demnach sind beide Programme nicht ¨aquivalent, weil das einetmpm¨oglicherweise ver¨andert, das andere aber nicht. Wird im weiteren Programmverlauf der intmpgespeicherte Wert aber nicht mehr verwendet, w¨are es gerechtfertigt, beide Programme als ¨aquivalent zu betrachten.

Definition 8 ( ¨Aquivalenz von Programmen). Zwei Programmec1undc2sind ¨aquivalent bez¨uglich der Variablen V ⊆Var, falls f¨ur alle σ gilt:

• Wennhc1, σi ⇓σ1 f¨ur einσ1, dann gibt es ein σ2 mit hc2, σi ⇓σ2 und σ1(x) =σ2(x) f¨ur alle x∈V.

• Wennhc2, σi ⇓σ2 f¨ur einσ2, dann gibt es ein σ1 mit hc1, σi ⇓σ1 und σ1(x) =σ2(x) f¨ur alle x∈V.

In obigem Beispiel sind beide Programme ¨aquivalent bez¨uglich der Variablen {x,y}.

Die beiden Bedingungen sind klassische Simulationsbedingungen in beide Richtungen, man kann sie auch f¨ur Small-Step-Semantiken entsprechend formulieren. Da die Big-Step-Semantik deterministisch ist, lassen sie sich wie folgt vereinfachen.

(18)

Lemma 11 ( ¨Aquivalenz f¨ur deterministische Programme). Zwei Programme c1 und c2 sind

¨

aquivalent bez¨uglich V genau dann, wenn

(i) c1 terminiert genau dann, wennc2 terminiert, d.h., es gibt einσ1 mithc1, σi ⇓σ1 genau dann, wenn es ein σ2 mithc2, σi ⇓σ2 gibt.

(ii) Wennhc1, σi ⇓σ1 undhc2, σi ⇓σ2, dann σ1(x) =σ2(x) f¨ur alle x∈V.

(19)

4 Ein Compiler f¨ ur While

Reale Rechner verarbeiten Assembler-Code und keine Syntaxb¨aume. Sprachen wieWhile sind damit nicht direkt auf einem solchen Rechner ausf¨uhrbar, sondern m¨ussen ¨ubersetzt werden. Die Regeln der Big-Step-Semantik (und auch der Small-Step-Semantik) lassen sich beispielsweise direkt in Prolog- Regeln konvertieren, die ein Prolog-Interpreter ausf¨uhren kann. Der f¨ur die Regeln spezialisierte Interpreter f¨uhrt dann das Programm aus, ¨ubersetzt es also in eine Ausf¨uhrung des Programms auf einem konkreten Rechner. Dabei wird aber das auszuf¨uhrende Programm selbst nicht in eine f¨ur den Rechner geeignetere Darstellung ¨ubersetzt.

Direkter geht es, wenn man einen solchen Rechner und seine Instruktionen selbst formal modelliert und einen ¨Ubersetzer (Compiler) f¨urWhile-Programme schreibt, der semantisch ¨aquivalente Programme erzeugt. In diesem Abschnitt wird dieser Ansatz f¨ur ein sehr abstraktes Modell eines solchen Rechners f¨ur die SpracheWhile ausgearbeitet.

4.1 Ein abstraktes Modell eines Rechners ASM

Der abstrakte Rechner hat einen Speicher f¨ur Daten und eine Liste von Befehlen, die er abarbeitet. In unserem einfachen Modell reichen drei Assembler-Befehle (zusammengefasst in der MengeAsm), zwei zur Kontrollflusssteuerung und eine Datenoperation.

Definition 9 (Instruktionen in ASM).

ASSN x Aexp Zuweisung

JMPk relativer Sprung (k∈Z)

JMPF kBexp bedingter, relativer Sprung (k∈Z)

Ein Assembler-Programm (ASM) P besteht aus einer unver¨anderlichen Liste der abzuarbeitenden Befehle, angefangen mit dem ersten der Liste.

Neben dem Zustand f¨ur den Variableninhalt gibt ein Programmz¨ahler an, die wievielte Instruktion der Liste die n¨achste ist, die abgearbeitet werden muss. Notation f¨ur einen einzelnen Ausf¨uhrungsschritt:

P ` hi, σi → hi0, σ0i. F¨ur ein gegebenes Programm (Instruktionsliste) P transformiert die i-te Instruktion in P den Zustand σ in den Zustand σ0 und i0 bezeichnet die n¨achste auszuf¨uhrende Instruktion.Pi bezeichne dasi-te Element vonP und ist nur definiert, wenninicht negativ und kleiner als die L¨ange vonP ist.

Definition 10 (Semantik von ASM).

Die SemantikP ` h, i → h , i einesASM-ProgrammsP ist durch folgende Regeln definiert.

Assn: Pi=ASSNx a

P ` hi, σi → hi+ 1, σ[x7→ AJaKσ]i Jmp: Pi =JMPk P ` hi, σi → hi+k, σi

JmpFT: Pi =JMPF k b BJbKσ =tt

P ` hi, σi → hi+ 1, σi JmpFF: Pi =JMPF k b BJbKσ=ff P ` hi, σi → hi+k, σi Wenninegativ oder gr¨oßer als die L¨ange vonP ist, ist keine Ausf¨uhrung m¨oglich.

(20)

Die gesamte Semantik eines Programms P in einem Zustandσ ist wieder ¨uber die maximalen Ablei- tungssequenzen vonh0, σigegeben; oder aber durch die blockierten Konfigurationenhi0, σi, die in der transitiven H¨ulleP ` hi, σi→ hi 0, σ0i von h0, σi aus erreichbar sind, und die Existenz unendlicher Ausf¨uhrungen P ` h0, σi→.

Ubung:¨ Welche Konstrukte und Regeln der Assembler-Sprache sind ¨uberfl¨ussig und k¨onnten durch die anderen simuliert werden?

4.2 Ein Compiler von While nach ASM

SeiP++P0 die Verkettung der beiden Listen P und P0 und |P|die L¨ange vonP.

Definition 11 (Compiler). Der Compiler vonWhilenachASMsei durch die Funktion comp definiert:

comp(skip) = []

comp(x := a) = [ASSN x a]

comp(c1; c2) = comp(c1) ++ comp(c2)

comp(if (b) then c1 else c2) = [JMPF k1 b] ++ comp(c1) ++[JMPk2] ++ comp(c2) wobei k1 =|comp(c1)|+ 2 und k2 =|comp(c2)|+ 1 comp(while (b) do c) = [JMPF (k+ 2)b] ++ comp(c) ++[JMP−(k+ 1)]

wobei k=|comp(c)|

Beispiel 6.

Das Kompilat des Programmsz := 0; while (y <= x) do (z := z + 1; x := x - y)ist:

[ASSN z 0, JMPF 4 (y <= x), ASSN z(z + 1), ASSN x (x - y), JMP−3]

F¨ur(if (x <= y) then x := x + y; y := x - y; x := x - y else y := x); z := 5ergibt sich folgendes Kompilat – unabh¨angig von der Klammerung der Sequenz imthen-Zweig:

[JMPF 5 (x <= y), ASSN x (x + y), ASSN y(x - y), ASSN x (x - y), JMP2, ASSN y x, ASSN z 5 ] Ubersetzt man¨ if (x <= -1) then x := -1 * x else skip, so erh¨alt man:

[JMPF 3 (x <= -1), ASSN x(-1 * x), JMP 1]

4.3 Korrektheit des Compilers

Ein Compiler soll die Semantik eines Programms nicht ver¨andern. Dadurch, dass die Semantik von Whileund ASM formal gegeben sind, l¨asst sich das auch exakt formulieren und beweisen:

• Wennhc, σi ⇓σ0, dann comp(c)` h0, σi→ h|comp(c)|, σ 0i.

• Wenn es keine Big-Step-Ableitung f¨urhc, σi gibt, dann comp(c)` h0, σi→. Theorem 12 (ASM simuliert Big-Step).

Wennhc, σi ⇓σ0, dann comp(c)` h0, σi→ h|comp(c)|, σ 0i.

(21)

Dieses Theorem folgt direkt aus folgender Verallgemeinerung, die erlaubt, dass die Maschinenbefehlsse- quenz in beliebigen Code eingebettet ist.

Lemma 13. SeienP1 und P2 beliebige ASM Programme.

Wennhc, σi ⇓σ0, dann P1++ comp(c) ++P2` h|P1|, σi→ h|P 1|+|comp(c)|, σ0i.

Beweis. Beweis durch Regelinduktion ¨uber hc, σi ⇓σ0,P1 und P2 beliebig. Notation:|c|=|comp(c)|

• FallSkipBS: Zu zeigen:

F¨ur alle P1 und P2 giltP1++ comp(skip) ++P2 ` h|P1|, σi→ h|P 1|+|skip|, σi.

Trivial wegen|skip|= 0.

• FallAssBS: Zu zeigen: F¨ur alle P1 undP2 gilt

P1++ comp(x := a) ++P2 ` h|P1|, σi→ h|P 1|+|x := a|, σ[x7→ AJaKσ]i.

Beweis: P1++[ASSN x a] ++P2 ` h|P1|, σi → h|P1|+ 1, σ[x7→ AJaKσ]i nach Regel Assn, da (P1++[ASSN x a] ++P2)|P1|=ASSNx a.

• FallSeqBS: Zu zeigen: F¨ur alle P1 und P2 gilt

P1++ comp(c1; c2) ++P2` h|P1|, σi→ h|P 1|+|c1; c2|, σ00i.

Induktionsannahmen: F¨ur beliebige P1 und P2 gelten P1++ comp(c1) ++P2 ` h|P1|, σi→ h|P 1|+|c1|, σ0i und P1++ comp(c2) ++P2 ` h|P1|, σ0i→ h|P 1|+|c2|, σ00i.

Instanziiert man in der ersten Induktionsannahme P2 mit comp(c2) ++P2 und P1 der zweiten Induktionsannahme mit P1++ comp(c1), so gelten:

P1++ comp(c1) ++(comp(c2) ++P2)` h|P1|, σi→ h|P 1|+|c1|, σ0i

(P1++ comp(c1)) ++ comp(c2) ++P2` h|P1++ comp(c1)|, σ0i→ h|P 1++ comp(c1)|+|c2|, σ00i Ausrechnen und Transitivit¨at von → liefern die Behauptung.

• FallIfTTBS: Zu zeigen: F¨ur alle P1 und P2 gilt P1++ comp(if (b) then c1 else c2) ++P2 ` h|P1|, σi→ h|P 1|+|if (b) then c1 else c2|, σ0i.

Induktionsannahmen:

BJbKσ =ttund f¨ur beliebigeP1 und P2 gilt P1++ comp(c1) ++P2 ` h|P1|, σi→ h|P 1|+|c1|, σ0i.

Beweis mit der Induktionsannahme, bei der P1 alsP1++[JMPF(|c1|+ 2)b] und P2 als [JMP(|c2|+ 1)] ++ comp(c2) ++P2 instanziiert werden:

P1++[JMPF (|c1|+ 2)b] ++ comp(c1) ++[JMP(|c2|+ 1)] ++ comp(c2) ++P2 ` h|P1|, σi → h|P1|+ 1, σi→ h|P 1|+ 1 +|c1|, σ0i → h|P1|+ 2 +|c1|+|c2|, σ0i

• FallIfFFBS: Analog zuIfTTBS.

• FallWhileTTBS: Zu zeigen: F¨ur alle P1 undP2 gilt

P1++ comp(while (b) do c) ++P2 ` h|P1|, σi→ h|P 1|+|while (b) do c|, σ00i.

Induktionsannahmen:BJbKσ =ttund f¨ur beliebige P1 undP2 gelten

P1++ comp(c) ++P2 ` h|P1|, σi → h|P 1|+|c|, σ0i und P1++ comp(while (b) do c) ++P2 ` h|P1|, σ0i→ h|P 1|+|while (b) do c|, σ00i.

Beweis mit entsprechend instanziierten Induktionshypothesen und RegelJmpFT: P1++[JMPF (|c|+ 2)b] ++ comp(c) ++[JMP−(|c|+ 1)] ++P2 `

h|P1|, σi → h|P1|+ 1, σi→ h|P 1|+ 1 +|c|, σ0i → h|P1|, σ0i→ h|P 1|+|while (b) do c|, σ00i

Referenzen

ÄHNLICHE DOKUMENTE

Schwerpunkt auf dem Lamda-Kalk¨ ul und Typsystemen, mit sehr guten Erkl¨arungen, auch zu weiterf¨ uhrenden Themen. • Glynn Winskel: The Formal Semantics of

Bei der Big-Step- Semantik interessiert nur der Endzustand einer Programmausf¨ uhrung, w¨ahrend eine Ableitungsfol- ge in der Small-Step-Semantik zus¨atzlich alle

Genau genommen ist dies erst einmal ¨ uberhaupt keine Definition, weil nicht klar ist, dass es eine Funktion mit dieser Eigenschaft ¨ uberhaupt gibt und dass diese Eigenschaft

Gleichbedeutend damit ist, dass man f¨ ur eine operationale oder denotationale Semantik beweist, dass die Regeln der axiomatischen Semantik korrekt sind: Wenn ⊢ { P } c { Q }, dann

Gleichbedeutend damit ist, dass man f¨ ur eine operationale oder denotationale Semantik beweist, dass die Regeln der axiomatischen Semantik korrekt sind: Wenn ` { P } c { Q }, dann

In dieser Aufgabe soll eine Small-Step-Semantik f¨ ur While mit goto definiert werden.. Dazu sei Lab eine Menge von Labels, die typischerweise mit l

Die in der Vorlesung vorgestelle Big-Step-Semantik f¨ ur Prozeduren mit einem Parameter wertet den ¨ ubergebenen Parameter beim Aufruf aus und ¨ ubergibt nur den Wert an die

Gleichbedeutend damit ist, dass man f¨ ur eine operationale oder denotationale Semantik beweist, dass die Regeln der axiomatischen Semantik korrekt sind: Wenn ⊢ { P } c { Q }, dann