Korrekte Software: Grundlagen und Methoden Vorlesung 1 vom 07.04.15: Einführung
Serge Autexier, Christoph Lüth
Universität Bremen
Sommersemester 2016
18:09:49 2016-07-07 1 [66]
Organisatorisches
I Veranstalter:
Christoph Lüth christoph.lueth@dfki.de
MZH 4185, Tel. 59830
Serge Autexier serge.autexier@dfki.de
Cartesium 2.11, Tel. 59834
I Termine:
I Vorlesung: Montag, 16 – 18, MZH 1460
I Übung: Donnerstag, 14 – 16, MZH 1460
I Webseite:
http://www.informatik.uni-bremen.de/~cxl/lehre/ksgm.ss16
Korrekte Software 2 [66]
Prüfungsformen
I 10 Übungsblätter (geplant)
I Prüfungsform 1:
I Bearbeitung derÜbungsblätter,
I Fachgespräch,
I Noteaus den Übungsblättern.
I Prüfungsform 2:
I Mind. ausreichende Bearbeitung der Übungsblätter (50%),
I mündliche Prüfung,
I Noteaus der Prüfung.
Korrekte Software 3 [66]
Warum Korrekte Software?
Korrekte Software 4 [66]
Software-Disaster I: Therac-25
Korrekte Software 5 [66]
Bekannte Software-Disaster II: Ariane-5
Korrekte Software 6 [66]
Bekannte Software-Disaster III: Airbus A400M
Korrekte Software 7 [66]
Inhalt der Vorlesung
Korrekte Software 8 [66]
Themen
Korrekte Software im Lehrbuch:
I Spielzeugsprache
I Wenig Konstrukte
I Kleine Beispiele
Korrekte Software im Einsatz:
I Richtige Programmiersprache
I Mehr als nur ganze Zahlen
I Skalierbarkeit — wie können große Programme verifiziert werden?
Korrekte Software 9 [66]
Inhalt
I Grundlagen:
I DerHoare-Kalkül — Beweis der Korrektheit von Programmen
I Bedeutung von Programmen:Semantik
I Erweiterung der Programmkonstrukte und des Hoare-Kalküls:
1. ReicheDatenstrukturen(Felder,struct) 2. Funktion und Prozeduren (Modularität) 3. Referenzen (Zeiger)
I Übungsbetrieb:
I Betrachtete Programmiersprache: “C0” (erweiterte Untermenge von C)
I Entwicklung eines Verifikationswerkzeugs in Scala
I Beweise mit Isabelle (mächtigerTheorembeweiser)
Korrekte Software 10 [66]
Nächste Woche
I Aussagenlogik
I Erstes Übungsblatt
Korrekte Software 11 [66]
Introduction to Scala
Based on the “Scala Training Course” by Fredrik Vraalsen (fredrik@vraalsen.no) and Alf Kristian Støyle (alf.kristian@gmail.com)
of scalaBin released under
Creative Commons Attribution 3.0 Unported license
Korrekte Software 12 [66]
Conciseness
public class Person { private int age;
private String name;
public Person(int age, String name) {
this.age=age;
this.name=name;
}
public int getAge() { return this.age;
}
public void setAge(int age) { this.age=age;
}
public String getName() { return this.name;
}
public void setName(String name) {
this.name=name;
} }
class Person(var age: Int , var name:
String)
Korrekte Software 13 [66]
Conciseness
List <Person> persons = ...
List <Person> adults =newLinkedList<Person>();
List <Person> kids =newLinkedList<Person>();
for (Person person : persons) { if (person.getAge() < 18) {
kids . add(person);
} else {
adults . add(person);
} }
val ( kids , adults ) = persons. partition (_.age< 18)
Korrekte Software 14 [66]
Conciseness
String s ="!em esreveR";
System.out. println (s . reverse () ) ;
val s : java . lang . String ="!em esreveR"
println (s . reverse )
=>Reverse me!
Korrekte Software 15 [66]
Higher-Order
List <Person> persons = ...
List <Person> adults =newLinkedList<Person>();
List <Person> kids =newLinkedList<Person>();
for (Person person : persons) { if (person.getAge() < 18) {
kids . add(person);
} else {
adults . add(person);
} }
val ( kids , adults ) = persons. partition (_.age< 18)
Korrekte Software 16 [66]
Java Interaction, Higher-Order
BufferedReader reader =null; try {
reader =newBufferedReader(newFileReader("f.txt")) ; System.out. println ( reader . readLine () ) ;
} finally {
if ( reader !=null) { try {
reader . close () ;
} catch (IOException e) { // Exception on close, ignore }
} }
using(newBufferedReader(newFileReader("f. txt "))) { reader =>println(reader . readLine () )
}
def using [A, B <: {def close () : Unit}] ( closeable : B) (f : B=>
A): A =
try { f ( closeable ) } finally { closeable . close () }
Korrekte Software 17 [66]
val myList = List(1, 2, 3) val res = (10 /: myList) (_+_)
=> ??
Korrekte Software 18 [66]
Scala
I Object oriented and functional
I Statically typed
I Java compatible
I Compiles to Java bytecode (and CLR)
I Existing libraries/frameworks
I Better Java
Korrekte Software 19 [66]
Topics
I Basic syntax
I REPL
I First class functions
I Pattern matching
I OO and traits
I Functional programming
I Higher-Order Functions
I Implicits
I (XML)
Korrekte Software 20 [66]
Basic Syntax
;
I Is optional (inferred)
I Except if multiple statements in a line
val s ="hello"
println (s) val s ="hello"; println (s)
Korrekte Software 21 [66]
Type Definitions
Scala Java
s:String String s
i:Int int i / Integer i
Korrekte Software 22 [66]
Variables
Scala Java
s:String String s
i:Int int i / Integer i
val s = "Hello World" public final String s = "Hello World";
var i = 1 public int i = 1;
private var k = 3 private int j = 3;
Korrekte Software 22 [66]
Methods
Scala
def add(x: Int , y: Int ) : Int = { x + y
}
def add(x: Int , y: Int ) = x + y def doSomething(text: String ) { }
Java
public int add(int x, int y) { return x + y;
}
public void doSometing(String text) {
}
Korrekte Software 23 [66]
Methods
Scala
myObject.myMethod(1) myObject myMethod(1) myObject myMethod 1
myObject.myOtherMethod(1, 2) myObject myOtherMethod(1, 2) myObject.myMutatingMethod() myObject.myMutatingMethod // myObject myMutatingMethod
Java
myObject.myMethod(1);
myObject.myOtherMethod(1, 2);
myObject.myMutatingMethod()
Korrekte Software 24 [66]
Methods
Scala
override def toString = ...
Java Override
public String toString () {...}
Korrekte Software 25 [66]
Classes And Constructors
Scala
class Person(val name: String)
Java
public class Person { private final String name;
public Person(String name) { this.name = name;
}
public String getName() { return name;
} }
Korrekte Software 26 [66]
Traits (= Interface + Mixin)
Scala
trait Shape { def area : Double }
class Circle extends Object with Shape
Java
interface Shape { public double area () ; }
public class Circle extends Object
implementsShape
Korrekte Software 27 [66]
No “Static” in Scala
Scala
object PersonUtil { val AgeLimit = 18 def countPersons(persons:
List[Person]) = ...
}
Java
public class PersonUtil { public static final int
AGE_LIMIT = 18;
public static int
countPersons(List<Person>
persons) { ...
} }
Korrekte Software 28 [66]
if-then-else
Scala if (foo) { ...
} else if (bar) { ...
} else { ...
}
Java if (foo) { ...
} else if (bar) { ...
} else { ...
}
Korrekte Software 29 [66]
For-Loops
Scala
for ( i <−0 to 3) { ...
}
for (s <−args) println (s)
Java
for (int i = 0; i < 4; i++) { ...
}
for ( String s : args ) { System.out. println (s) ; }
Korrekte Software 30 [66]
While-Loops
Scala
while (true) { ...
}
Java
while (true) { ...
}
Korrekte Software 31 [66]
Exceptions
Scala
throw newException(" ... ") try {
} catch {
case e : IOException=>...
} finally { }
Java
throw newException(" ... ") try {
} catch (IOException e) { ...
} finally { }
Korrekte Software 32 [66]
Varargs
Scala
def foo( values : String∗){ }
foo("bar", "baz")
val arr = Array("bar", "baz") foo( arr : _∗)
Java
public void foo( String ...
values ){ }
foo("bar", "baz");
String [] arr =
newString []{"bar", "baz"}
foo( arr ) ;
Korrekte Software 33 [66]
(Almost) everything is an expression
val res = if (foo) x else y
val res =for ( i <−1 to 10) yield i // List(1, ..., 10) val res =try { x } catch { ...; y } finally { } // x or y
Korrekte Software 34 [66]
Collections – List
Scala
val numbers =List(1, 2, 3) val numbers = 1:: 2 :: 3 :: Nil
numbers(0)
=>1
Java
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.get(0);
=>1
Korrekte Software 35 [66]
Collections – Map
Scala
var m = Map(1−>"apple") m+=2−>"orange"
m(1)
=>"apple"
Java
Map<Int, String> m =
newHashMap<Int, String>();
m.put(1, "apple") ; m.put(2, "orange") ; m.get(1);
=>apple
Korrekte Software 36 [66]
Generics
Scala List[ String ]
Java
List<String>
Korrekte Software 37 [66]
Tuples
Scala
val tuple : Tuple2[ Int , String ] = (1, "apple")
val quadruple =
(2, "orange", 0.5d, false)
Java
Pair<Integer, String > tuple = newPair<Integer, String>(1,
"apple")
... ;−)
Korrekte Software 38 [66]
Packages
Scala
packagemypackage ...
Java
packagemypackage;
...
Korrekte Software 39 [66]
Imports
Scala
import java . util .{List, ArrayList }
import java . io ._
import java . sql .{Date=>SDate}
Java
import java . util .List import java . util . ArrayList import java . io .∗
???
Korrekte Software 40 [66]
Nice to Know
Scala
println ("Hello") val line = readLine()
sys . error ("Bad") 1 + 1
1 .+(1)
1 == newObject 1 eq newObject
"""A\sregex""". r
s"3 + 4 = ${3 + 4}"// "3 + 4 = 7"
Java
System.out. println ("Hello") ;
BufferedReader r =newBufferedReader(new InputStreamRead(System.in));
String line = r.readLine () ;
throw newRuntimeException("Bad") newInteger(1) . toInt () +new
Integer (1) . toInt () ;
newInteger(1) . equals (newObject());
newInteger(1) == newObject();
java . util . regex . Pattern .compile("A\\sregex");
"3 + 4 = "+ (3 + 4)
Korrekte Software 41 [66]
Topics
I Basic syntax
I REPL
I First class functions
I Pattern matching
I OO and traits
I Functional programming
I Higher-Order Functions
I Implicits
I (XML)
Korrekte Software 42 [66]
REPL - Read eval print loop
I Command line shell for on-the-fly execution of Scala statements
I bin/scala
Korrekte Software 43 [66]
IDE and Build Tools
I Scala IDE for Eclipse is the officially supported Platform by the creators of Scala.http://scala-ide.org/
I Scala Plugin for IDEA is very good too. (And IDEA is avaliable in a free edition)
I There used to be support for Netbeans, but that seems to be dead right now.
Build Tool
I SBT
(Scala Build Tool) is an Mawen compatible build tool for Scala and Java http://www.scala-sbt.org/
Korrekte Software 44 [66]
First Class Functions
val even = Function[Int , Boolean] { def apply( i : Int ) = i % 2==0 }
val even: ( Int =>Boolean) = (i: Int) =>i % 2== 0 val even = (i : Int ) =>i % 2== 0
even.apply(42) // true
even(13) // false
Korrekte Software 45 [66]
First Class Functions
val numbers =List(1, 2, 3, 4, 5)
numbers. filter (even) // List(2, 4) numbers. filter (( i : Int ) =>i > 2) // List(3, 4, 5) numbers. filter ( i =>i > 2) // List(3, 4, 5) numbers. filter (_ > 2) // List(3, 4, 5)
Korrekte Software 46 [66]
Collections
numbers. filter ( i =>i > 2) // List(3, 4, 5) numbers.find( i =>i > 2) // Some(3) numbers. exists ( i =>i > 2) // true numbers. forall ( i =>i > 2) // false
numbers.map(i=> i∗2) // List(2, 4, 6, 8, 10) numbers.foldLeft (0) { (a, b) => a + b } // 15
Korrekte Software 47 [66]
Deferred execution - constructed example
helloButton . addActionListener (e =>
println ("Hello World!") )
Korrekte Software 48 [66]
Closure
val people =List(Person("Alf") , Person(" Fredrik ")) val name ="Fredrik"
val nameFilter = (p: Person) => p.name==name people . filter (nameFilter) // Person("Fredrik")
Korrekte Software 49 [66]
Closures
val people =List(Person("Alf") , Person(" Fredrik ")) var name ="Fredrik"
val nameFilter = (p: Person) => p.name==name people . filter (nameFilter) // Person("Fredrik") name ="Alf"
people . filter (nameFilter) // Person(Älf")
Korrekte Software 50 [66]
Pattern Matching
myObjectmatch{
case 1 =>println(" First was hit ") case 2 =>println("Second was Hit") case _=>println("Unknown") }
Korrekte Software 51 [66]
Pattern Matching
myObjectmatch{
case i : Int =>println("Found an int") case s : String =>println("Found a String") case _=>println("Unknown")
}
Korrekte Software 52 [66]
Pattern Matching
myObjectmatch{
case i : Int =>println("Found an int") case s : String =>println("Found an String") case other =>println("Unknown "+ other) }
Korrekte Software 53 [66]
Pattern Matching
myObjectmatch{
case i : Int if i == 1=>println("Found an int") case s : String =>println("Found a String") case other =>println("Unknown "+ other) }
Korrekte Software 54 [66]
Pattern Matching
val res = myObjectmatch{
case i : Int if i ==1 =>"Found an int"
case s : String => "Found a String"
case other =>"Unknown "+ other }
Korrekte Software 55 [66]
Pattern Matching
val res = myObjectmatch{
case ( first , second) =>second case ( first , second, third ) =>third }
Korrekte Software 56 [66]
Pattern Matching
val mathedElement = listmatch{
case List( firstElement , lastElement) =>firstElement case List( firstElement , _∗)=>firstElement
case _=>"failed"
}
Korrekte Software 57 [66]
Pattern Matching
def length ( list : List[_]) : Int = list match{
case Nil =>0
case head :: tail =>1 + length(tail) }
Korrekte Software 58 [66]
Pattern Matching
public static Integer getSecondOr0(List<Integer> list ) { if ( list != null && list . size () >= 2) {
return list . get(1) ; } else {
return 0;
} }
⇓
def second_or_0(list :List[ Int ]) = list match{ case List(_, x, _∗)=>x
case _=> 0 }
Korrekte Software 59 [66]
Case classes
I Class types that can be used in pattern matching
I Generated into your class:
I equals
I hashCode
I toString
Korrekte Software 60 [66]
Case classes
abstract class Person(name: String)
case class Man(name: String)extendsPerson(name) case class Woman(name: String, children: List[Person])
extends Person(name)
Korrekte Software 61 [66]
Case Classes
p match{
case Man(name)=> println("Man with name "+ name) case Woman(name, children)=>println("Woman with name"+
name +" and with " + children. size +" children ") }
Korrekte Software 62 [66]
Regular Expressions
val regex ="""(\d+)(\w+)""".r val myString = ...
val res : String = myStringmatch{ case regex( digits , word)=> digits case _=>"None"
}
Korrekte Software 63 [66]
Regular Expressions
val regex ="""(\d+)(\w+)""".r val myString = ...
val res : Option[ String ] = myStringmatch{ case regex( digit , word) =>Some(digit) case _=>None
}
Korrekte Software 64 [66]
Options
I Never NullPointerException again!
I Option has two possible values:
I Some(value)
I None
val someOption: Option[String] = Some("value") val noOption: Option[String ] = None
Korrekte Software 65 [66]
Options
def getValue(s : Any): Option[ String ]
getValue(object) match{
case Some(value)=>println(value) case None=>println("Nothing") }
val result = getValue(object) .getOrElse("Nothing")
Korrekte Software 66 [66]
Korrekte Software: Grundlagen und Methoden Vorlesung 2 vom 10.04.16: Die Floyd-Hoare-Logik
Serge Autexier, Christoph Lüth
Universität Bremen
Sommersemester 2016
18:09:51 2016-07-07 1 [21]
Fahrplan
I Einführung
I Die Floyd-Hoare-Logik
I Operationale Semantik
I Denotationale Semantik
I Äquivalenz der Semantiken
I Verifikation: Vorwärts oder Rückwärts?
I Korrektheit des Hoare-Kalküls
I Einführung in Isabelle/HOL
I Weitere Datentypen: Strukturen und Felder
I Funktionen und Prozeduren
I Referenzen und Zeiger
I Frame Conditions & Modification Clauses
I Ausblick und Rückblick
Korrekte Software 2 [21]
Idee
I Was wird hier berechnet?
I Wie können wir dasbeweisen?
I Wir berechnen symbolisch, welche Werte Variablen über den
Programmverlauf annehmen.
p= 1 ; c= 1 ;
w h i l e ( c <= n ) { p := p ∗ c ; c := c + 1 ; }
I Um Aussagen über ein Program zu beweisen, benötigen wir einen Formalismus (eineLogik), die es erlaubt, Zusicherungen über Werte von Variablen zu bestimmten Ausführungszeitpunkten (im Programm) aufzuschreibenund zu beweisen.
I Dazu müssen wir auch dieBedeutung (Semantik) des Programmes definieren — die Frage “Was tut das Programm” mathematischexakt beantworten.
Korrekte Software 3 [21]
Idee
I Was wird hier berechnet?p =n!
I Wie können wir dasbeweisen?
I Wir berechnen symbolisch, welche Werte Variablen über den
Programmverlauf annehmen.
p= 1 ; c= 1 ;
w h i l e ( c <= n ) { p := p ∗ c ; c := c + 1 ; }
I Um Aussagen über ein Program zu beweisen, benötigen wir einen Formalismus (eineLogik), die es erlaubt, Zusicherungen über Werte von Variablen zu bestimmten Ausführungszeitpunkten (im Programm) aufzuschreibenund zu beweisen.
I Dazu müssen wir auch dieBedeutung (Semantik) des Programmes definieren — die Frage “Was tut das Programm” mathematischexakt beantworten.
Korrekte Software 3 [21]
Idee
I Was wird hier berechnet?p =n!
I Wie können wir dasbeweisen?
I Wir berechnen symbolisch, welche Werte Variablen über den
Programmverlauf annehmen.
{1≤n}
p= 1 ; c= 1 ;
w h i l e ( c <= n ) { p := p ∗ c ; c := c + 1 ; }
{p=n!}
I Um Aussagen über ein Program zu beweisen, benötigen wir einen Formalismus (eineLogik), die es erlaubt, Zusicherungen über Werte von Variablen zu bestimmten Ausführungszeitpunkten (im Programm) aufzuschreibenund zu beweisen.
I Dazu müssen wir auch dieBedeutung (Semantik) des Programmes definieren — die Frage “Was tut das Programm” mathematischexakt beantworten.
Korrekte Software 3 [21]
Idee
I Was wird hier berechnet?p =n!
I Wie können wir dasbeweisen?
I Wir berechnen symbolisch, welche Werte Variablen über den
Programmverlauf annehmen.
{1≤n}
p= 1 ; c= 1 ;
w h i l e ( c <= n ) { p := p ∗ c ; c := c + 1 ; }
{p=n!}
I Um Aussagen über ein Program zu beweisen, benötigen wir einen Formalismus (eineLogik), die es erlaubt, Zusicherungen über Werte von Variablen zu bestimmten Ausführungszeitpunkten (im Programm) aufzuschreibenund zu beweisen.
I Dazu müssen wir auch dieBedeutung (Semantik) des Programmes definieren — die Frage “Was tut das Programm” mathematischexakt beantworten.
Korrekte Software 3 [21]
Semantik von Programmiersprachen
Drei wesentliche Möglichkeiten:
I Operationale Semantikbeschreibt die Bedeutung eines Programmes, indem die Ausführung auf einer abstrakten Maschine beschrieben wird.
I Denotationale Semantikbildet jedes Programm auf ein mathematisches Objekt (meist ein partielle Funktion zwischen Systemzuständen) ab.
I Axiomatische Semantikbeschreibt die Bedeutung eines Programmes durch Beweisregeln, mit welchem sich gültige Eigenschaften herleiten lassen. Das prominenteste Beispiel hierzu ist die Floyd-Hoare-Logik.
Korrekte Software 4 [21]
Drei Semantiken — Eine Sicht
p = 1;
c := 1;
while (c <= n) { p= p * c;
c= c + 1;
}
Operational
Axiomatisch Denotational
Programm
I Jede Semantik ist eine Sichtauf das Program.
I Diese Semantiken sollten alleäquivalentsein. Wir müssen sie also in Beziehung setzen, und zeigen dass sie diegleiche Sichtergeben.
I Für die axiomatische Semantik (die
Floyd-Hoare-Logik) ist das die Frage derKorrektheit der Regeln.
Korrekte Software 5 [21]
Floyd-Hoare-Logik
I Grundbaustein der Floyd-Hoare-Logik sindZusicherungen der Form {P}c{Q}(Floyd-Hoare-Tripel), wobei P dieVorbedingung ist,c das Programm, undQ dieNachbedingung.
I Die Logik hat sowohllogische Variablen (zustandsfrei), und
Programmvariablen(deren Wert sich über die Programmausführung ändert).
I Die Floyd-Hoare-Logik hat eine wesentlichesPrinzipand einenTrick.
I DasPrinzipist die Abstraktion vom Programmzustand durch eine logische Sprache; insbesondere wird dieZuweisung durch Substitution modelliert.
I DerTrickbehandelt Schleifen: Iteration im Programm entspricht Rekursion in der Logik. Ein Beweis ist daher induktiv, und benötig eine Induktionsannahme — eineInvariante.
Korrekte Software 6 [21]
Unsere Programmiersprache
Wir betrachten einen Ausschnitt der ProgrammierspracheC (C0).
Ausbaustufe 1 kennt folgende Konstrukte:
I Typen: int;
I Ausdrücke: Variablen, Literale (für ganze Zahlen), arithmetische Operatoren (für ganze Zahlen), Relationen (==,!=,<=, . . . ), boolsche Operatoren (&&, ||);
I Anweisungen:
I Fallunterscheidung (if. . .else. . . ), Iteration (while), Zuweisung, Blöcke;
I Sequenzierung und leere Anweisung sind implizit
Korrekte Software 7 [21]
C0: Ausdrücke und Anweisungen
Aexp a::=N|Loc |a1+a2 |a1−a2 |a1∗a2 |a1/a2 Bexp b ::=0|1|a1 ==a2 |a1! =a2
|a1 <=a2 |!b |b1&&b2 |b1||b2
Exp e :=Aexp |Bexp Stmt c ::= Loc=Exp;
| if( b ) c1 else c2
| while ( b ) c
| {c∗}
Korrekte Software 8 [21]
Semantik von C0
I Die (operationale) Semantik einer imperativen Sprache wie C0 ist ein Zustandsübergang: das System hat einen impliziten Zustand, der durch Zuweisung vonWerten an Adressengeändert werden kann.
I Konkretes Beispiel:n= 3 p ?
c ? n 3
p 1 c ? n 3
p 1 c 1 n 3
p 1 c 1 n 3
. . . p 6 c 4 n 3
Systemzustände
I Ausdrücke werten zuWerten Val (hier ganze Zahlen) aus.
I AdressenLocsind hier Programmvariablen (Namen)
I EinSystemzustandbildet Adressen auf Werte ab: Σ =Loc*Val
I Ein Programm bildet einen Anfangszustandmöglicherweiseauf einen Endzustand ab (wenn esterminiert).
I Zusicherungen sind Prädikate über dem Systemzustand.
Korrekte Software 9 [21]
Floyd-Hoare-Tripel
Partielle Korrektheit (|={P}c{Q})
c ist partiell korrekt, wenn für alle Zustände σ, dieP erfüllen:
wenn die Ausführung vonc mitσ in σ0 terminiert, dann erfülltσ0 Q
Totale Korrektheit (|= [P]c[Q])
c ist total korrekt, wenn für alle Zustandeσ, dieP erfüllen:
die Ausführung vonc mit σ in σ0 terminiert, und σ0 erfülltQ.
I |={1}while(1){ } {1} gilt
I |= [1] while(1){ }[1] gilt nicht
Korrekte Software 10 [21]
Regeln der Floyd-Hoare-Logik
I Die Floyd-Hoare-Logik erlaubt es, Zusicherungen der Form
` {P}c{Q} syntaktischherzuleiten.
I DerKalkül der Logik besteht aus sechs Regeln der Form
` {P1}c1{Q1}. . .` {Pn}cn{Qn}
` {P}c{Q}
I Für jedes Konstrukt der Programmiersprache gibt es eine Regel.
Korrekte Software 11 [21]
Regeln der Floyd-Hoare-Logik: Zuweisung
` {P[[[e]]/X]}x =e{P}
I Eine Zuweisungx=e ändert den Zustand so dass an der Stellex jetzt der Wert vone steht. Damit nachher das PrädikatP gilt, muss also vorherdas Prädikat gelten, wenn wirx durch [[e]] ersetzen.
I Es ist völlig normal (aber dennoch falsch) zu denken, die Substitution gehöre eigentlich in die Nachbedingung.
I Beispiele:
x = 5 {x <10}
x = x+ 1
Korrekte Software 12 [21]
Regeln der Floyd-Hoare-Logik: Zuweisung
` {P[[[e]]/X]}x =e{P}
I Eine Zuweisungx=e ändert den Zustand so dass an der Stellex jetzt der Wert vone steht. Damit nachher das PrädikatP gilt, muss also vorherdas Prädikat gelten, wenn wirx durch [[e]] ersetzen.
I Es ist völlig normal (aber dennoch falsch) zu denken, die Substitution gehöre eigentlich in die Nachbedingung.
I Beispiele:
{5<10←→(x <10)[x/5]}
x = 5 {x <10}
x = x+ 1
Korrekte Software 12 [21]
Regeln der Floyd-Hoare-Logik: Zuweisung
` {P[[[e]]/X]}x =e{P}
I Eine Zuweisungx=e ändert den Zustand so dass an der Stellex jetzt der Wert vone steht. Damit nachher das PrädikatP gilt, muss also vorherdas Prädikat gelten, wenn wirx durch [[e]] ersetzen.
I Es ist völlig normal (aber dennoch falsch) zu denken, die Substitution gehöre eigentlich in die Nachbedingung.
I Beispiele:
{5<10←→(x <10)[x/5]}
x = 5 {x <10}
x = x+ 1 {x <10}
Korrekte Software 12 [21]
Regeln der Floyd-Hoare-Logik: Zuweisung
` {P[[[e]]/X]}x =e{P}
I Eine Zuweisungx=e ändert den Zustand so dass an der Stellex jetzt der Wert vone steht. Damit nachher das PrädikatP gilt, muss also vorherdas Prädikat gelten, wenn wirx durch [[e]] ersetzen.
I Es ist völlig normal (aber dennoch falsch) zu denken, die Substitution gehöre eigentlich in die Nachbedingung.
I Beispiele:
{5<10←→(x <10)[x/5]}
x = 5 {x <10}
{x <9←→x+ 1<10}
x = x+ 1 {x <10}
Korrekte Software 12 [21]
Regeln der Floyd-Hoare-Logik: Fallunterscheidung und Sequenzierung
` {A&&[[b]]}c0{B} ` {A&&¬[[b]]}c1{B}
` {A} if(b) c0 else c1{B}
I In der Vorbedingung desif-Zweiges gilt die Bedingung b, und im else-Zweig gilt die Negation ¬b.
I Beide Zweige müssem mit derselben Nachbedingung enden.
` {A}c{B} ` {B} {cs} {C}
` {A} {c cs} {C}
I Hier wird ein ZwischenzustandB benötigt.
Korrekte Software 13 [21]
Regeln der Floyd-Hoare-Logik: Iteration
` {A∧[[b]]}c{A}
` {A} while(b) c{A∧ ¬[[b]]}
I Iteration korrespondiert zuInduktion.
I Bei (natürlicher) Induktion zeigen wir, dass diegleicheEigenschaft P für 0 gilt, und dass wenn sie fürP(n) gilt, daraus folgt, dass sie für P(n+ 1) gilt.
I Analog dazu benötigen wir hier eineInvarianteA, die sowohl vorals auchnach dem Schleifenrumpf gilt.
I In derVorbedingungdes Schleifenrumpfeskönnen wir die Schleifenbedingung [[b]] annehmen.
I DieVorbedingungder Schleife ist die InvarianteA, und die Nachbedingungder Schleife istA und die Negation der Schleifenbedingung [[b]].
Korrekte Software 14 [21]
Regeln der Floyd-Hoare-Logik: Weakening
A0 −→A ` {A}c{B} B−→B0
` {A0}c{B0}
c
All possible program states
A B
c
All possible program states B' A'
I |={A}c{B}: Ausführung von c startet in Zustand, in dem Agilt, und endet (ggf) in Zustand, in demB gilt.
I Zustandsprädikate beschreiben Mengen von Zuständen:P ⊆Q gdw.
P −→Q.
I Wir könnenAzuA0 einschränken (A0 ⊆A oderA0 −→A), oderB zu B0 vergrößern (B ⊆B0 oderB−→B0), und erhalten |={A0}c{B0}.
Korrekte Software 15 [21]
Regeln der Floyd-Hoare-Logik: Weakening
A0 −→A ` {A}c{B} B−→B0
` {A0}c{B0}
c
All possible program states
A B
c
All possible program states A' B'
I |={A}c{B}: Ausführung von c startet in Zustand, in dem Agilt, und endet (ggf) in Zustand, in demB gilt.
I Zustandsprädikate beschreiben Mengen von Zuständen:P ⊆Q gdw.
P −→Q.
I Wir könnenAzuA0 einschränken (A0 ⊆A oderA0 −→A), oder B zu B0 vergrößern (B ⊆B0 oderB−→B0), und erhalten |={A0}c{B0}.
Korrekte Software 15 [21]
Überblick: die Regeln des Floyd-Hoare-Kalküls
` {P[[[e]]/X]}x =e{P}
` {A} { } {A}
` {A}c{B} ` {B} {cs} {C}
` {A} {c cs} {C}
` {A∧[[b]]}c0{B} ` {A∧ ¬[[b]]}c1{B}
` {A} if(b) c0 else c1{B}
` {A∧[[b]]}c{A}
` {A} while(b) c{A∧ ¬[[b]]}
A0 −→A ` {A}c{B} B−→B0
` {A0}c{B0}
Korrekte Software 16 [21]
Eigenschaften der Floyd-Hoare-Logik
Korrektheit
Wenn ` {P}c{Q}, dann |={P}c{Q}
I Wenn wir eine Korrektheitsaussage herleiten können, dann gilt sie auch.
I Wird gezeigt, indem wir|={P}c{Q} durch die anderen Semantiken definieren, und zeigen, dass alle Regeln diese Gültigkeit erhalten.
Relative Vollständigkeit
Wenn |={P}c{Q}, dann ` {P}c{Q} (bis auf Weakening)
I Wenn eine Korrektheitsaussage nicht beweisen werden kann (aber sie stimmt), dann liegt das immer daran, dass einelogische Aussage(in einer Anwendung der Weakening-Regelx) nicht bewiesen werden kann.
I Das ist zu erwarten: alle interessanten Logiken sind unvollständig.
Korrekte Software 17 [21]
Wie wir Floyd-Hoare-Beweise aufschreiben
// {P}
// {P1} x= e ; // {P2} // {P3}
w h i l e ( x< n ) { // {P3∧x<n}
// {P4} z= a ; // {P3} }
// {P3∧ ¬(x<n)}
// {Q}
I Beispiel zeigt: ` {P}c{Q}
I Programm wird mit gültigen Zusicherungen annotiert.
I Vor einer Zeile steht die Vorbedingung, danach die Nachbedingung.
I Implizite Anwendung der Sequenzenregel.
I Weakening wird notiert durch mehrere Zusicherungen, und mussbewiesenwerden.
I Im Beispiel:P−→P1,
P2−→P3,P3∧x<n−→P4, P3∧ ¬(x <n)−→Q.
Korrekte Software 18 [21]
Warum Verifikation?
Hier sind Varianten des Fakultätsbeispiels.
Welche sind korrekt?
// {1≤n}
p = 1 ; c = 1 ;
w h i l e ( c<=n ) { c = c +1;
p = p∗c ; }
// {p=n!}
// {1≤n}
p = 1 ; c = 1 ;
w h i l e ( c<n ) { c = c +1;
p = p∗c ; }
// {p=n!}
//{1≤N∧n=N}
p = 1 ;
w h i l e (0<n ) { p = p∗n ; n = n−1;
}
//{p=N!}
Korrekte Software 19 [21]
Eine Handvoll Beispiele
// {y =Y} x= 1 ;
w h i l e ( y != 0 ) { y= y−1;
x= 2∗x ; }
// {x = 2Y}
// {a≥0∧b≥0}
r= b ; q= 0 ;
w h i l e ( b <= r ) { r= r−y ;
q= q +1;
}
// {a=b∗q+r∧r <b}
//{0≤a}
t= 1 ; s= 1 ; i = 0 ;
w h i l e ( s <= a ) { t= t+ 2 ;
s= s+ t ; i = i + 1 ; }
//{i2≤a∧a<(i+ 1)2}
Korrekte Software 20 [21]
Eine Handvoll Beispiele
// {y =Y ∧y≥0}
x= 1 ;
w h i l e ( y != 0 ) { y= y−1;
x= 2∗x ; }
// {x = 2Y}
// {a≥0∧b≥0}
r= b ; q= 0 ;
w h i l e ( b <= r ) { r= r−y ;
q= q +1;
}
// {a=b∗q+r∧r <b}
//{0≤a}
t= 1 ; s= 1 ; i = 0 ;
w h i l e ( s <= a ) { t= t+ 2 ;
s= s+ t ; i = i + 1 ; }
//{i2≤a∧a<(i+ 1)2}
Korrekte Software 20 [21]
Zusammenfassung
I Floyd-Hoare-Logik zusammengefasst:
I Die Logik abstrahiert über konkrete Systemzustände durchZusicherungen (Hoare-Tripel|={P}c{Q}).
I Zusicherungen sind boolsche Ausdrücke, angereichert durch logische Variablen und Programmvariablen.
I Wir können partielle Korrektheitsaussgen der Form|={P}c{Q} herleiten (oder totale,|= [P]c[Q]).
I Zuweisungen werden durch Substitution modelliert, d.h. die Menge der gültigen Aussagen ändert sich.
I Für Iterationen wird eineInvariantebenötigt (dienichthergeleitet werden kann).
I Die Korrektheit hängt sehr davon ab, wieexaktwir die Semantik der Programmiersprache beschreiben können.
Korrekte Software 21 [21]
Korrekte Software: Grundlagen und Methoden Vorlesung 3 vom 18.04.16: Operationale Semantik
Serge Autexier, Christoph Lüth
Universität Bremen
Sommersemester 2016
18:09:52 2016-07-07 1 [18]
Fahrplan
I Einführung
I Die Floyd-Hoare-Logik
I Operationale Semantik
I Denotationale Semantik
I Äquivalenz der Semantiken
I Verifikation: Vorwärts oder Rückwärts?
I Korrektheit des Hoare-Kalküls
I Einführung in Isabelle/HOL
I Weitere Datentypen: Strukturen und Felder
I Funktionen und Prozeduren
I Referenzen und Zeiger
I Frame Conditions & Modification Clauses
I Ausblick und Rückblick
Korrekte Software 2 [18]
Zutaten
// GGT(A,B)
i f ( a == 0 ) r= b ; e l s e {
w h i l e ( b != 0 ) { i f ( a <= b )
b = b − a ; e l s e a = a − b ; }
r = a ; }
I Programme berechnenWerte
I Basierend auf
I Werte sindVariablenzugewiesen
I Evaluation vonAusdrücken
I Folgt dem Programmablauf
Korrekte Software 3 [18]
Unsere Programmiersprache
Wir betrachten einen Ausschnitt der ProgrammierspracheC (C0).
Ausbaustufe 1 kennt folgende Konstrukte:
I Typen: int;
I Ausdrücke: Variablen, Literale (für ganze Zahlen), arithmetische Operatoren (für ganze Zahlen), Relationen (==,!=,<=, . . . ), boolsche Operatoren (&&, ||);
I Anweisungen:
I Fallunterscheidung (if. . .else. . . ), Iteration (while), Zuweisung, Blöcke;
I Sequenzierung und leere Anweisung sind implizit
Korrekte Software 4 [18]