Korrekte Software: Grundlagen und Methoden Vorlesung 11 vom 19.06.18: Funktionen und Prozeduren
Serge Autexier, Christoph Lüth Universität Bremen Sommersemester 2018
12:09:46 2018-08-01 1 [29]
Fahrplan
I Einführung
I Operationale Semantik I Denotationale Semantik
I Äquivalenz der Operationalen und Denotationalen Semantik I Die Floyd-Hoare-Logik
I Invarianten und die Korrektheit des Floyd-Hoare-Kalküls I Strukturierte Datentypen
I Modellierung und Spezifikation I Verifikationsbedingungen I Vorwärts mit Floyd und Hoare I Funktionen und Prozeduren I Referenzen
I Ausblick und Rückblick
Korrekte Software 2 [29]
Funktionen & Prozeduren
I Funktionensind das zentrale Modularisierungskonzept von C
I Kleinste Einheit
I NB. Prozeduren sind nur Funktionen vom Typvoid I In objektorientierten Sprachen: Methoden
I Funktionen mit (implizitem) erstem Parameterthis
I Wie behandeln wir Funktionen?
Korrekte Software 3 [29]
Modellierung und Spezifikation von Funktionen
Wir brauchen:
(1)Von Anweisungen zu Funktionen: Deklarationen und Parameter
(2)Semantik von Funktionsdefinition und Funktionsaufruf
(3)Spezifikation von Funktionen
(4)Beweisregeln für Funktionsdefinition und Funktionsaufruf
Korrekte Software 4 [29]
Von Anweisungen zu Funktionen
I Erweiterung unserer Kernsprache um Funktionsdefinition und Deklarationen:
FunDef::=FunHeader FunSpec+Blk FunHeader::=Type Idt(Decl∗)
Decl::=Type Idt Blk::={Decl∗Stmt}
Type::=char|int|Struct|Array Struct::=struct Idt?{Decl+}
Array::=Type Idt[Aexp]
I Abstrakte Syntax (konkrete Syntax mischtTypeundIdt, Kommata bei Argumenten, . . . )
I Größe von Feldern:konstanterAusdruck I FunSpecspäter
Korrekte Software 5 [29]
Funktionsaufrufe und Rückgaben
Neue Ausdrücke und Anweisungen:
I Funktionsaufrufe I Return-Anweisung
Aexpa::= Z|C|Lexp|a1+a2|a1−a2|a1∗a2|a1/a2
| Idt(Exp∗)
Bexp b::=1|0|a1==a2|a1<a2|!b|b1&&b2|b1||b2 Expe:=Aexp|Bexp
Stmtc ::= l=e|c1;c2| { } |if(b)c1 elsec2
| while(b)/∗∗inv a∗/c|/∗∗{a}∗/
| Idt(a∗)
| returna?
Korrekte Software 6 [29]
Rückgabewerte
I Problem:returnbricht sequentiellen Kontrollfluss:
i f ( x == 0 ) r e t u r n −1;
y = y / x ; // Wird nicht immer erreicht I Lösung 1: verbieten!
I MISRA-C (Guidelines for the use of the C language in critical systems):
Rule 14.7 (required)
A function shall have a single point of exit at the end of the function.
I Nicht immer möglich, unübersichtlicher Code. . .
I Lösung 2: Erweiterung der Semantik von Σ*Σ zu Σ*(Σ + Σ×V)
Korrekte Software 7 [29]
Erweiterte Semantik
I Denotat einer Anweisung: Σ*(Σ + Σ×V) Σ*(Σ + Σ×VU) I Abbildung von Ausgangszustand Σ auf:
ISequentieller Folgezustand, oder
IRückgabewert und Rückgabezustand I Was ist mitvoid?
IErweiterte Werte:VU def=V+{∗}
I Komposition zweier Anweisungenf,g: Σ*(Σ + Σ×VU):
g◦Sf(σ)def=
(g(σ0) f(σ) =σ0 (σ0,v) f(σ) = (σ0,v)
Korrekte Software 8 [29]
Semantik von Anweisungen
C[[.]] :Stmt→Σ*(Σ + Σ×VU) C[[x=e]] ={(σ, σ[a/x])|(σ,a)∈ A[[e]]}
C[[c1;c2]] =C[[c1]]◦SC[[c2]] Komposition wie oben C[[{ }]] =IdΣ IdΣ:={(σ, σ)|σ∈Σ}
C[[if(b)c0 elsec1]] ={(σ, σ0)|(σ,true)∈ B[[b]]∧(σ, σ0)∈ C[[c0]]}
∪ {(σ, σ0)|(σ,false)∈ B[[b]]∧(σ, σ0)∈ C[[c1]]}
mitσ0∈Σ∪(Σ×VU) C[[return e]] ={(σ,(σ,a))|(σ,a)∈ A[[e]]}
C[[return]] ={(σ,(σ,∗))}
C[[while(b)c]] =fix(Γ)
Γ(ψ)=def{(σ, σ0)|(σ,true)∈ B[[b]]∧(σ, σ0)∈ψ◦SC[[c]]}
∪ {(σ, σ)|(σ,false)∈ B[[b]]}
Korrekte Software 9 [29]
Semantik von Funktionsdefinitionen
Dfd[[.]] :FunDef→Vn*Σ*Σ×VU Das Denotat einer Funktion ist eine Anweisung, die über den tatsächlichen Werten für die Funktionsargumente parametriert ist.
Dfd[[f(t1p1,t2p2, . . . ,tnpn)blk]] = λv1, . . . ,vn.{(σ,(σ0,v))|
(σ,(σ0,v))∈ Dblk[[blk]]◦S{(σ, σ[v1/p1, . . . ,vn/pn])}}
I Die Funktionsargumente sind lokale Deklarationen, die mit den Aufrufwerten initialisiert werden.
IInsbesondere können sie lokal in der Funktion verändert werden.
I VonDblk[[blk]] sind nurRückgabezuständeinteressant.
IKein „fall-through“
Korrekte Software 10 [29]
Semantik von Blöcken und Deklarationen
Dblk[[.]] :Blk*Σ*(Σ + Σ×VU) Dd[[.]] :Decl*Σ*(Σ + Σ×VU) Blöcke bestehen aus Deklarationen und einer Anweisung:
Dblk[[decls stmts]] =C[[stmts]]◦SDd[[decls]]
Dd[[t i]] ={(σ, σ[⊥/i])}
I Verallgemeinerung auf Sequenz von Deklarationen
Korrekte Software 11 [29]
Funktionsaufrufe
I Aufruf einer Funktion:f(t1, . . . ,tn):
IAuswertung der Argumentet1, . . . ,tn IEinsetzen in die SemantikDfd[[f]]
I Call by name, call by value, call by reference. . . ?
IC kennt nur call by value (C-Standard 99, §6.9.1. (10))
IWas ist mitSeiteneffekten?Wie können wir Werteändern?
IErst mal gar nicht. . .
Korrekte Software 12 [29]
Funktionsaufrufe
I Um eine Funktionf aufzurufen, müssen wir (statisch!) die Semantik derDefinitionvonf dem Bezeichnerf zuordnen.
I Deshalb brauchen wir eineUmgebung(Environment):
Env=Id*[[FunDef]]
=Id*VN*Σ*(Σ×Vu)
I Das Environment istzusätzlicher Parameterfür alle Definitionen
Korrekte Software 13 [29]
Semantik von Funktionsaufrufen
A[[f(t1, . . . ,tn)]]Γ ={(σ,v)| ∃σ0,v.(σ,(σ0,v))∈Γ(f)(v1, . . . ,vn)
∧(σ,vi)∈ A[[ti]]Γ}
C[[f(t1, . . . ,tn)]]Γ ={(σ, σ0)| ∃σ0.(σ,(σ0,∗))∈Γ(f)(v1, . . . ,vn)
∧(σ,vi)∈ A[[ti]]Γ}
C[[x=f(t1, . . . ,tn)]]Γ ={(σ, σ0[v/x])| ∃σ0,v.(σ,(σ0,v))∈Γ(f)(v1, . . . ,vn)
∧(σ,vi)∈ A[[ti]]Γ}
I Aufruf einer nicht-definierten Funktionf oder mit falscher Anzahln von Parametern ist nicht definiert
IMuss durchstatische Analyseverhindert werden I Aufruf von FunktionA[[f(t1, . . . ,tn)]] ignoriert Endzustand I Aufruf von ProzedurC[[f(t1, . . . ,tn)]] ignoriert Rückgabewert I Besser: Kombination mit Zuweisung
Korrekte Software 14 [29]
Spezifikation von Funktionen
I WirspezifizierenFunktionen durchVor-undNachbedingungen
I Ähnlich den Hoare-Tripeln, aber vereinfachte Syntax
I Behavioural specification, angelehnt an JML, OCL, ACSL (Frama-C)
I Syntaktisch:
FunSpec::= /**preBexppostBexp*/
Vorbedingung presp; Σ→B
Nachbedingung postsp; Σ×(Σ×VU)→B
\old(e) Wert voneimVorzustand
\result Rückgabewertder Funktion
Korrekte Software 15 [29]
Beispiel: Fakultät
i n t f a c (i n t n ) /∗∗ p r e 0≤n;
p o s t \result==n! ;
∗/
{ i n t p ; i n t c ; p= 1 ; c= 1 ;
w h i l e ( c<= n ) /∗∗ i n v p== (c−1)!∧c≤n+ 1∧0<c ∗/ { p= p∗c ;
c= c +1;
} r e t u r n p ; }
Korrekte Software 16 [29]
Beispiel: Suche
i n t f i n d m a x (i n t a [ ] , i n t a _ l e n ) /∗∗ p r e \array(a,a_len) ; ∗/
/∗∗ p o s t ∀i.0≤i<a_len−→a[i]≤\result; ∗/
{
i n t x ; i n t j ; x= INT_MIN ; j= 0 ; w h i l e ( j < a _ l e n )
/∗∗ i n v (∀i.0≤i<j−→a[i]≤x)∧j≤a_len; ∗/
{
i f ( a [ j ]> x ) x= a [ j ] ; j= j +1;
} r e t u r n x ; }
Korrekte Software 17 [29]
Semantik von Spezifikationen
I Vorbedingung: Auswertung alsB[[sp]] Γ über dem Vorzustand I Nachbedingung: Erweiterung vonB[[.]] undA[[.]]
IAusdrücke können in Vor- oder Nachzustand ausgewertet werden.
I\resultkann nicht in Funktionen vom Typvoidauftreten.
Bsp[[.]] :Env→Bexp*(Σ×(Σ×VU))→B Asp[[.]] :Env→Aexp*(Σ×(Σ×VU))→V Bsp[[!b]] Γ ={((σ,(σ0,v)),1)|((σ,(σ0,v)),false)∈ Bsp[[b]]Γ}
∪ {((σ,(σ0,v)),0)|((σ,(σ0,v)),true)∈ Bsp[[b]]Γ}
. . .
Bsp[[\old(e)]] Γ ={((σ,(σ0,v)),b)|(σ,b)∈ B[[e]] Γ}
Asp[[\old(e)]] Γ ={((σ,(σ0,v)),a)|(σ,a)∈ A[[e]] Γ}
Asp[[\result]] Γ ={((σ,(σ,v)),v)}
Bsp[[preppostq]] Γ ={(σ,(σ0,v))|σ∈ B[[p]] Γ∧(σ0,(σ,v))∈ Bsp[[p]] Γ}
Korrekte Software 18 [29]
Gültigkeit von Spezifikationen
I Die Semantik von Spezifikationen erlaubt uns die Definition der semantischen Gültigkeit.
preppostq|=FunDef
⇐⇒ ∀v1, . . . ,vn.Dfd[[FunDef]] Γ∈ Bsp[[preppostq]] Γ
I Γ enthält globale Definitionen, insbesondere andere Funktionen.
I Wie passt das zu|={P}c{Q}für Hoare-Tripel?
I Wiebeweisenwir das? Erweiterungdes Hoare-Kalküls
Korrekte Software 19 [29]
Erweiterung des Floyd-Hoare-Kalküls
C[[.]] :Stmt→Σ*(Σ + Σ×VU) Hoare-Tripel: zusätzliche Spezifikation fürRückgabewert.
Partielle Korrektheit (|={P}c{Q|QR})
cistpartiell korrekt, wenn für alle Zuständeσ, diePerfüllen:
I die Ausführung voncmitσinσ0regulär terminiert, so dassσ0die SpezifikationQerfüllt,
I oder die Ausführung voncinσ0mit dem Rückgabewertvterminiert, so dass (σ0,v) die RückgabespezifikationQRerfüllt.
|={P}c{Q|QR} ⇐⇒
∀σ. σ|=B[[P]]Γ =⇒ ∃σ0.(σ, σ0)∈ C[[c]]Γ∧σ0|=B[[Q]]Γ
∨
∃σ0,v.(σ,(σ0,v))∈ C[[c]]Γ∧(σ0,v)|=B[[QR]]Γ
Korrekte Software 20 [29]
Kontext
I Wir benötigen ferner einenKontextΓ, der Funktionsbezeichnern ihre Spezifikation(Vor/Nachbedingung) zuordnet.
I Γ(f) =∀x1, . . . ,xn.(P,Q), für Funktionf(x1, . . . ,xn) mit VorbedingungPund NachbedingungQ.
I Notation: Γ|={P}c{Q|QR}und Γ` {P}c{Q|QR}
I Korrektheit gilt immer nur imKontext, dadurch kann jede Funktion separat verifiziert werden (Modularität)
Korrekte Software 21 [29]
Erweiterung des Floyd-Hoare-Kalküls: return
Γ` {Q}return{P|Q} Γ` {Q[e/\result]}return e{P|Q}
I Beireturnwird die RückgabespezifikationQzur Vorbedingung, die reguläre Nachfolgespezifikation wird ignoriert, da die Ausführung von returnkein Nachfolgezustand hat.
I returnohne Argument darf nur bei einer NachbedingungQauftreten, die kein\resultenthält.
I Beireturnmit Argument ersetzt der Rückgabewert den\resultin der Rückgabespezifikation.
Korrekte Software 22 [29]
Erweiterung des Floyd-Hoare-Kalküls: Spezifikation
P=⇒P0[yi/\old(yi)] Γ[f 7→ ∀x1, . . . ,xn.(P,Q)]` {P0}blk{Q|Q}
Γ`f(x1, . . . ,xn)/** prePpostQ*/{ds blk}
I Die Parameterxiwerden per Konvention nur alsxireferenziert, aber es ist immer der Wert imVorzustandgemeint (eigentlich\old(xi)).
I Variablen unterhalb von\old(y) werden bei der Substitution (Zuweisungsregel)nicht ersetzt!
I \old(y) wird beim Weakening von der VorbedingungPersetzt
Korrekte Software 23 [29]
Erweiterung des Floyd-Hoare-Kalküls: Aufruf
Γ(f) =∀x1, . . . ,xn.(P,Q),f vom Typvoid Γ` {Yj=yj&&P[ti/xi]}
f(t1, . . . ,tn)
{Q[ti/xi][Yj/\old(yj)]|QR} Γ(f) =∀x1, . . . ,xn.(P,Q) Γ` {Yj=yj&&P[ti/xi]}
x=f(t1, . . . ,tn)
{Q[ti/xi][Yj/\old(yj)][x/\result]|QR} I Γ mussf mit der Vor-/NachbedingungP,Qenthalten I InPundQwerden Parameterxidurch Argumentetiersetzt.
I y1, . . . ,ymsind die als\old(yj) inQauftretenden Variablen I Y1, . . . ,Ymdürfen nicht inPoderQenthalten sein I Im ersten Fall (Aufruf als Prozedur) enthältQkein\result
Korrekte Software 24 [29]
Erweiterter Floyd-Hoare-Kalkül I
Γ` {P} {} {P|QR}
Γ` {P}c1{R|QR} Γ` {R}c2{Q|QR} Γ` {P}c1;c2{Q|QR}
Γ` {Q[e/x]}x=e{Q|QR}
Γ` {P∧b}c{P|QR} Γ` {P}while(b)c{P∧ ¬b|QR} Γ` {P∧b}c1{Q|QR} Γ` {P∧ ¬b}c2{Q|QR}
Γ` {P}if(b)c1 elsec2{Q|QR} P−→P0 Γ` {P0}c{Q0|R0} Q0−→Q R0−→R
Γ` {P}c{Q|R}
Korrekte Software 25 [29]
Erweiterter Floyd-Hoare-Kalkül II
Γ` {Q}return{P|Q} Γ` {Q[e/\result]}return e{P|Q}
Γ[f7→(P,Q)]` {Xi=xi∧Yj=yj∧P}
blk
{Q[Xi/xi][yj/\old(yj)]|Q[Xi/xi][yj/\old(yj)]}
Γ`f(x1, . . . ,xn)/** prePpostQ**/{ds blk}
Γ(f) =∀x1, . . . ,xn.(P,Q),f vom Typvoid Γ` {Yj=yj∧P[ti/xi]}
f(t1, . . . ,tn)
{Q[ti/xi][Yj/\old(yj)]|QR} Γ(f) =∀x1, . . . ,xn.(P,Q) Γ` {Yj=yj∧P[ti/xi]}
x=f(t1, . . . ,tn)
{Q[ti/xi][Yj/\old(yj)][x/\result]|QR}
Korrekte Software 26 [29]
Beispiel: die Fakultätsfunktion, rekursiv
i n t f a c (i n t x ) /∗∗ p r e 0≤x;
p o s t\result=x! ∗/
{
i n t r = 0 ;
i f ( x == 0 ) { r e t u r n 1 ; } r = f a c ( x− 1 ) ;
r e t u r n r∗ x ; }
Korrekte Software 27 [29]
Beobachtungen
I Der Aufruf einer Funktionersetztdie momentane Nachbedingung — das ist ein Problem
I Wir brauchen keine Invariante mehr — ist durch die Nachbedingung gegeben
I Rekursion benötigt keine Extrabehandlung
ITermination von rekursiven Funktionen wird extra gezeigt
Korrekte Software 28 [29]
Zusammenfassung
I Funktionen sindzentrales Modularisierungskonzept I Wir müssen Funktionenmodularverifizieren können I Erweiterung derSemantik:
I Semantik von Deklarationen und Parameter — straightforward
I Semantik vonRückgabewerten— Erweiterung der Semantik
I Funktionsaufrufe— Environment, um Funktionsbezeichnern eine Semantik zu geben
I Erweiterung derSpezifikationen:
I Spezifikation von Funktionen:Vor-/Nachzustandstatt logischer Variablen I Erweiterung des Hoare-Kalküls:
I Environment, um andere Funktionen zu nutzen
I Gesonderte Nachbedingung für Rückgabewert/Endzustand
Korrekte Software 29 [29]