DL-Kalkül: Lokale Variablen

Werbung
DL-Kalkül: Lokale Variablen
vardecls right
x0
x 0 = τ , Γ ` hαx iϕ
Γ ` hlet x = τ in αiϕ
vardecls left
x0
hαx iϕ, x 0 = τ , Γ ` ∆
hlet x = τ in αiϕ, Γ ` ∆
x 0 sind neue Variablen (bezeichnen die lokalen Variablen). Dieselben
Regeln gelten auch für Boxen.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
197 / 290
Beispiel zur Korrekheit
m := x.first, x0 := x.rest;
while x0 6= [] do
{
if x0.first > m then m := x0.first ;
x0 := x0.rest
}
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
198 / 290
Beispiel zur Korrekheit
Maximum einer nichtleeren Liste nat. Zahlen x:
x 6= []
`h
m := x.first, x0 := x.rest;
while x0 6= [] do
{
if x0.first > m then m := x0.first ;
x0 := x0.rest
}
i
m = maxl(x)
wobei maxl([]) = 0, maxl(n + x) = max(n,maxl(x))
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
198 / 290
Zur nächsten Aufgabe
Invarianten vorher überlegen!!!
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
199 / 290
Korrektheit und Vollständigkeit der Kalküle
Satz: Die Programmkalküle
• Hoare-Kalkül für partielle Korrektheit
• Hoare-Kalkül für totale Korrektheit
• Dynamische Logik
sind korrekt. Z. B.
SP `HC ϕ {α} ψ ⇒ SP |= ϕ {α} ψ.
Sie sind alle unvollständig, d. h. SP |= ϕ {α} ψ impliziert nicht, dass
SP `HC ϕ {α} ψ gilt.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
200 / 290
Gegenbeispiel zur Vollständigkeit
Gegenbeispiel zur Vollständigkeit des Hoare-Kalküls:
Nat =
data specification
nat = 0 | +1 (-1 : nat)
end data specification
x = 0 ∧ y = y0
{
while y 6= 0 do
y := y -1; x := x +1
od
}
x = y0
Schleifeninvariante? x + y = y0 ? Eigentlich schon, aber keine Formel in
Nat.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
201 / 290
Unvollständigkeit der Programmkalküle
• Das Problem ist, dass man die Invariante mit den vorhandenen
Symbolen nicht ausdrücken kann.
• Die Invariante INV ist eine spezielle Induktionshypothese
Die Behauptung für n lautet: “Nach n Schleifendurchläufen gilt
INV”.
• Das Problem ist also dasselbe wie bei der Generiertheitsklausel.
Satz: Die Programmkalküle sind relativ vollständig: Wenn man alle
wahren Aussagen über den nat. Zahlen als Axiome hätte, dann könnte
jede wahre Aussage über Programmen bewiesen werden.
Intuition:
• Der Programmkalkül ist nicht schlimmer“ unvollständig, als die
”
Prädikatenlogik es war. Es fehlen keine Programmregeln.
• Wenn etwas nicht bewiesen werden kann, dann liegt es nur an
fehlenden Hilfsfunktionen/Axiomen für Datenstrukturen.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
202 / 290
Prozeduren und
Heuristiken für Programme
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
203 / 290
Prozeduren: Syntax
• Neues Programmkonstrukt: Prozeduraufruf p#(t;y)
• p# ist Prozedurname (das # ist übliche KIV-Konvention)
• Terme t der Sorten s sind Eingabe-Parameter
• Paarweise verschiedene Variablen y der Sorten s 0 sind
Ein-Ausgabe-Parameter
• s : s 0 heisst auch der (Aufrufs-)Modus der Prozedur
• Prozeduren p# ∈ Ps:s 0 sind neuer Bestandteil der Signatur einer
Spezifikation
• KIV: Deklaration zwischen predicates und variables per:
procedures p# s1 × ...× sn : s’1 × ...× s’m;
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
204 / 290
Prozeduren: Semantik
• Semantik: Prozeduren sind eine Relation über den Trägern der
Parametersorten: [[p#]] ⊆ As × As 0 × As 0
• (a, b, c) ∈ [[p]] bedeutet: Die Prozedur p#, aufgerufen mit
• Eingaben a für die Eingabe-Variablen
• Eingaben b für die Ein/Ausgabe-Variablen
terminiert mit Ausgabe c in den Ein/Ausgabe-Variablen
• Damit das stimmt: Kein Zugriff auf globale Variablen!
Ersatz: Zusätzliche Ein/Ausgabe-Parameter
• Normalfall in KIV: Funktionale Prozeduren:
Ein/Ausgabe-Variablen dienen nur zur Ausgabe:
c (und Terminierung) hängen nicht von b ab.
• Wenn nicht, Schlüsselwort nonfunctional am Ende der
Prozedurdefinition
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
205 / 290
Prozedurdeklarationen
• Möglich: Axiome für Prozeduren (Vor- und Nachbedingung)
• Normalerweise (hinter den axioms) Prozedurdeklarationen
declarations
f#(x; y)
{
if x = 0
then y := 1
else { f#(x -1;y); y := y * x }
}
• Erlaubt: (Gegenseitige) Rekursion
• Semantik: Prozeduraufruf erhält “die übliche” Semantik.
Formal: Vereinigung aller tiefenbeschränkten Rekursionen
(analog zu: Vereinigung über beschränkte Zahl von Schl.durchläufen)
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
206 / 290
Regeln für Prozeduraufrufe
Falls Prozedurdeklaration p#(y ; z).α gegeben:
x
y = σ, Γ ` hαz iϕ, ∆
Γ ` hp#(σ; x)iϕ, ∆
x
call right
y = σ, hαz iϕ, Γ ` ∆
hp#(σ; x)iϕ, Γ ` ∆
call left
Dabei: y sind die lokalen Variablen auf denen p# rechnet.
Sie dürfen in der Sequenz nicht frei vorkommen (evtl. umbenennen)
Die Regel gilt auch für Boxen statt Diamonds.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
207 / 290
Ein Beispiel
procedures MAXL# natlist : nat;
MAX# nat, nat : nat;
declaration
MAX#(m,n; n0)
{
if m < n then n0 := n else n0 := m
};
MAXL#(x; n)
{
if x = [] then n := 0
else { MAXL#(x.rest; n); MAX#(n,x.first;n) }
}
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
208 / 290
Programme als Voraussetzungen: execute call
Nützlich bei Induktion, um den Call aus der Induktionsvoraussetzung gegen den gerade aktuellen zu kürzen“.
”
execute call
Γ ` σ = τ, ∆
y
y
hp#(σ; x)i(x = y ), ϕx , Γ ` ψz , ∆
hp#(σ; x)iϕ, Γ ` hp#(τ ; z)iψ, ∆
contract call
Γ`σ=τ
y
y
hp#(σ; x)i(x = y ), ϕx , ψz , Γ ` ∆
hp#(σ; x)iϕ, hp#(τ ; z)iψ, Γ ` ∆
Regeln gelten (so) nur für funktionale (und damit auch deterministische)
Prozeduren (y jeweils neu). Für nichtfunktionale Prozeduren muß in der
ersten Prämisse x = z hinzugefügt werden.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
209 / 290
Zwischenzustände einführen: split left
Die folgende Regeln wird meist für α = Prozeduraufruf angewandt
(x = modifizierte Variablen von α, x 0 neu):
split left
x0
hαix = x 0 , ϕx , Γ ` ∆
hαiϕ, Γ ` ∆
• Führt einen Zustand x 0 am Ende von α ein, über den man “reden”
kann.
• Dieser wird bei der Anwendung von Lemmata der Form
hαi x = x0 ` ϕ
als Instanz für x0 gebraucht
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
210 / 290
Einfache Heuristiken für Programme
• symbolic execution: Wendet alle Regeln für Programme an, die keine
Fallunterscheidung ergeben: assign, if positive/negative, skip, abort,
let
• split left: Wendet die Regel split left an
• contract and execute: Wendet execute call, contract call an
Im Heuristik-Satz DL heuristics“ enthalten (zusammen mit simplifier,
”
quantifier closing, module specific). Kann immer verwendet werden.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
211 / 290
Fallunterscheidungs-Heuristiken
• conditional right split: wendet if right an
• conditional left split: wendet if left an
• dl case distinction: Fallunterscheidung (conjunction right etc.), aber
nur für Programmformeln
Im Heuristik-Satz DL Heuristics + Case Splitting“ enthalten. Sollte man
”
verwenden, wenn Beweisstruktur der Kontrollstruktur der Programme
folgt (meist der Fall).
Heuristik-Satz DL heuristics + Induction“ enthält zusätzlich Heuristiken
”
für (noethersche) Induktion (induction, apply ind once).
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
212 / 290
Heuristiken für Prozeduraufrufe
• calls nonrecursive: Führt alle nichtrekursiven Aufrufe aus
• calls concrete: Führt alle Aufrufe aus, die konkrete Parameter haben,
i. e. Terme die höchstens Parametervariablen enthalten
• weak unfold:
• Führt rekursive Prozeduren einmal aus, wenn sie in der
Induktionshypothese vorkommen. Höher in der Aufrufshierarchie
liegende Aufrufe bevorzugt.
• Weitere Aufrufe werden ausgeführt, wenn festgestellt wird, dass deren
Tests so ausgehen, dass kein weiterer rekursiver Aufruf auftritt.
• unfold: Führt zusätzlich rekursive Prozeduren (einmal) aus, bei denen
der rekursive Aufruf schon in der Sequenz vorkommt
DL Heuristics“ enthält weak unfold, DL Heuristics + Induction“ enthält
”
”
zusätzlich unfold.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
213 / 290
Nichtdeterministische
Programme
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
214 / 290
Nichtdet. Programme: Syntax
KIV kennt noch zwei Programmkonstrukte für nichtdeterministische
Programme:
• α or β: Wählt nichtdeterministisch eines der beiden Programme
• choose x with ϕ in α ifnone β
• Bindet lokale Variablen x (wie let) an irgendwelche Werte,
die ϕ erfüllen
• ϕ darf von anderen Programmvariablen als nur x abhängen
• Führt mit den lokalen Variablen α aus.
• Falls überhaupt keine passenden Werte für x existieren, die ϕ erfüllen,
wird β (ohne lokale Variablen) ausgeführt.
• ifnone abort kann weggelassen werden (default).
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
215 / 290
Beispiele für choose
Beispiele:
• choose n with true in α:
Rät beliebige natürliche Zahl
• choose n with n < m in α ifnone β:
Wählt natürliche Zahl n, die kleiner m ist, und führt α aus.
Wenn m = 0 gilt, wird stattdessen β ausgeführt.
• choose boolvar with true in if boolvar then α else β
Ist äquivalent zu α or β
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
216 / 290
Nichtdet. Programme: Semantik
Semantik von or:
[[α or β]] = [[α]] ∪ [[β]]
Semantik von choose:
[[choose x with ϕ in α ifnone β]]
v (x)
a
a
= {(v , wx ) | es gibt a mit A, vx |= ϕ und (vx , w ) ∈ [[α]]}
a
∪ {(v , w ) | (v , w ) ∈ [[β]] und es gibt kein a mit A, vx |= ϕ}
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
217 / 290
Ein Zusatzproblem für die Semantik
Was ist die Semantik von skip?
Was ist die Semantik von skip or abort?
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
218 / 290
Ein Zusatzproblem für die Semantik
Was ist die Semantik von skip?
Was ist die Semantik von skip or abort?
Antwort: Beide sind gleich: Identität auf allen Zuständen
Verhalten sich die Programme unterschiedlich?
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
218 / 290
Ein Zusatzproblem für die Semantik
Was ist die Semantik von skip?
Was ist die Semantik von skip or abort?
Antwort: Beide sind gleich: Identität auf allen Zuständen
Verhalten sich die Programme unterschiedlich?
Antwort: Ja, skip terminiert garantiert, skip or abort nicht.
Also: Die relationale Semantik kann nicht ausdrücken, dass ein
nichtdeterministisches Programm garantiert terminiert.
Damit kann es auch die dynamische Logik nicht:
hskip or aborti true besagt, dass es einen terminierenden Ablauf gibt.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
218 / 290
Garantierte Terminierung
Definieren eine zusätzliche zweite Semantik für Programme: α ↓ ⊆ ST
gibt die Menge der Zustände (ST = Menge der Variablenbelegungen), für
die α garantiert terminiert. Einige Fälle (while und Rekursion sind
schwierig) sind:
• abort ↓ = ∅
• skip ↓ = ST
• x := e ↓ = ST
• (α ∨ β) ↓ = α ↓ ∩ β ↓
• (α; β) ↓ = {v | v ∈ α ↓ und für alle w mit (v , w ) ∈ [[α]] gilt: w ∈ β ↓}
• choose x with ϕ in α ifnone β ↓ =
a
a
{v | es gibt a mit A, vx |= ϕ und für jedes solche a ist vx ∈ α ↓}
a
∪ { v | es gibt kein a mit A, vx |= ϕ und v ∈ β ↓}
Beachte: Die Definition der garantierten Terminierung von compounds
benutzt die relationale Semantik.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
219 / 290
Neuer Operator: strong diamond
Wir addieren einen neuen Operator ( strong diamond“) zur Logik.
”
h|α|i ϕ besagt: α terminiert garantiert, und in allen Endzuständen gilt ϕ
Formal: A, v |= h|α|iψ :⇔ v ∈ α ↓ und für alle w : (v , w ) ∈ [[α]] gilt:
A, w |= ψ.
Bemerkung: Der Operator wurde von E.W. Dijkstra 1976 erfunden, und
schreibt sich in der Literatur meist wp(α,ϕ) (von weakest
”
precondition“). Der Kalkül heisst deshalb auch wp-Kalkül.
Bemerkung: Die strong diamond-Klammern bekommt man mit F12
(KIV-Symbol) und dann { bzw. }.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
220 / 290
Kalkülregeln für or
Das Gute an strong diamonds: Für deterministische Programme sind die
Regeln für strong diamonds genau dieselben wie für diamonds.
or right
Γ ` hαi ψ, hβi ψ, ∆
Γ ` hα ∨ βi ψ, ∆
Γ ` [α] ψ, ∆
Γ ` [β] ψ, ∆
Γ ` [α ∨ β] ψ, ∆
Γ ` h|α|i ψ, ∆
Γ ` h|β|i ψ, ∆
Γ ` h|α ∨ β|i ψ, ∆
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
221 / 290
Kalkülregeln für choose
choose right
y
y
Γ ` ∃ y .ϕx ∧ hαx i ψ, (∀ x.¬ ϕ) ∧ hβi ψ, ∆
Γ ` hchoose x with ϕ in α ifnone βi ψ, ∆
y
y
ϕx , Γ ` [αx ] ψ, ∆
∀ x.¬ ϕ, Γ ` [β] ψ, ∆
Γ ` [choose x with ϕ in α ifnone β] ψ, ∆
y
y
ϕx , Γ ` h|αx |i ψ, ∆
∀ x.¬ ϕ, Γ ` h|β|i ψ, ∆
Γ ` h|choose x with ϕ in α ifnone β|i ψ, ∆
Die Variablen y sind neue Variablen (für die lokalen Versionen von x).
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
222 / 290
Kontrakte,
Abstrakte Datentypen
und Verfeinerung
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
223 / 290
Kontrakte
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
224 / 290
Vor- und Nachbedingungen, Kontrakte
Ein Kontrakt für eine Prozedur p (oder auch für eine Methode) besteht
(mindestens) aus
• einer Vorbedingung ϕ (präd.log. Formel)
• einer Nachbedingung ψ (präd.log. Formel)
• der Angabe der input-Parameter (incl. gelesene globale Variablen)
• der Angabe der output-Parameter (incl. geschrieben globale
Variablen).
• Dazu kommt natürlich eine informelle Beschreibung: U.a. Name und
Zweck der Operation, Querverweise zu Use Cases, etc.
Bemerkung: Für KIV-Prozeduren fehlen die globalen Variablen. Sie
müssen als I/O-Parameter addiert werden.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
225 / 290
Vor- und Nachbedingungen, Kontrakte
Definition: Eine Methode mit Implementierung mit Rumpf α erfüllt einen
Kontrakt, falls die Parameter korrekt gegeben und der Rumpf total
korrekt bzgl. Vor- und Nachbedingung ist. Formal also muss gelten:
• Im Hoare-Kalkül: ϕ hαi ψ
• In Dynamischer Logik: ϕ → hαi ψ
Bemerkung:(Vorbedingung in Kontrakten)
Wenn die Vorbedingung nicht eingehalten wird, darf beliebiges passieren:
Absturz, Exception, Nichtterminierung, reguläres Ergebnis, illegaler
Speicher etc.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
226 / 290
Zwei Beispiekontrakte
Beispiel 1 (Revertieren einer Liste):
• Eingabe und Ausgabe: Liste x
• Vorbedingung: x = y
• Nachbedingung x = reverse(y)
Beispiel 2 (Entfernen eines Element von einem Stack):
• Eingabe: Stack st
• Ausgabe: Modifizierter Stack st und Element a
• Vorbedingung: st = st0 ∧ st 6= emptystack
• Nachbedingung st = pop(st0 ) ∧ a = top(st0 )
y und st0 sind logische Variablen, die nur zur Spezifikation benötigt
werden. Alles andere sind Programmvariablen.
4. Juni 2012
D. Haneberg: Formale Methoden im Software Engineering
227 / 290
Herunterladen