• Keine Ergebnisse gefunden

Korrekte Software: Grundlagen und Methoden Vorlesung 1 vom 07.04.15: Einführung

N/A
N/A
Protected

Academic year: 2022

Aktie "Korrekte Software: Grundlagen und Methoden Vorlesung 1 vom 07.04.15: Einführung"

Copied!
358
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

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]

(2)

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]

(3)

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]

(4)

Warum Korrekte Software?

Korrekte Software 4 [66]

(5)

Software-Disaster I: Therac-25

Korrekte Software 5 [66]

(6)

Bekannte Software-Disaster II: Ariane-5

Korrekte Software 6 [66]

(7)

Bekannte Software-Disaster III: Airbus A400M

Korrekte Software 7 [66]

(8)

Inhalt der Vorlesung

Korrekte Software 8 [66]

(9)

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]

(10)

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]

(11)

Nächste Woche

I Aussagenlogik

I Erstes Übungsblatt

Korrekte Software 11 [66]

(12)

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]

(13)

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]

(14)

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]

(15)

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]

(16)

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]

(17)

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]

(18)

val myList = List(1, 2, 3) val res = (10 /: myList) (_+_)

=> ??

Korrekte Software 18 [66]

(19)

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]

(20)

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]

(21)

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]

(22)

Type Definitions

Scala Java

s:String String s

i:Int int i / Integer i

Korrekte Software 22 [66]

(23)

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]

(24)

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]

(25)

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]

(26)

Methods

Scala

override def toString = ...

Java Override

public String toString () {...}

Korrekte Software 25 [66]

(27)

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]

(28)

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]

(29)

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]

(30)

if-then-else

Scala if (foo) { ...

} else if (bar) { ...

} else { ...

}

Java if (foo) { ...

} else if (bar) { ...

} else { ...

}

Korrekte Software 29 [66]

(31)

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]

(32)

While-Loops

Scala

while (true) { ...

}

Java

while (true) { ...

}

Korrekte Software 31 [66]

(33)

Exceptions

Scala

throw newException(" ... ") try {

} catch {

case e : IOException=>...

} finally { }

Java

throw newException(" ... ") try {

} catch (IOException e) { ...

} finally { }

Korrekte Software 32 [66]

(34)

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]

(35)

(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]

(36)

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]

(37)

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]

(38)

Generics

Scala List[ String ]

Java

List<String>

Korrekte Software 37 [66]

(39)

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]

(40)

Packages

Scala

packagemypackage ...

Java

packagemypackage;

...

Korrekte Software 39 [66]

(41)

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]

(42)

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]

(43)

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]

(44)

REPL - Read eval print loop

I Command line shell for on-the-fly execution of Scala statements

I bin/scala

Korrekte Software 43 [66]

(45)

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]

(46)

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]

(47)

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]

(48)

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]

(49)

Deferred execution - constructed example

helloButton . addActionListener (e =>

println ("Hello World!") )

Korrekte Software 48 [66]

(50)

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]

(51)

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]

(52)

Pattern Matching

myObjectmatch{

case 1 =>println(" First was hit ") case 2 =>println("Second was Hit") case _=>println("Unknown") }

Korrekte Software 51 [66]

(53)

Pattern Matching

myObjectmatch{

case i : Int =>println("Found an int") case s : String =>println("Found a String") case _=>println("Unknown")

}

Korrekte Software 52 [66]

(54)

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]

(55)

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]

(56)

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]

(57)

Pattern Matching

val res = myObjectmatch{

case ( first , second) =>second case ( first , second, third ) =>third }

Korrekte Software 56 [66]

(58)

Pattern Matching

val mathedElement = listmatch{

case List( firstElement , lastElement) =>firstElement case List( firstElement , _∗)=>firstElement

case _=>"failed"

}

Korrekte Software 57 [66]

(59)

Pattern Matching

def length ( list : List[_]) : Int = list match{

case Nil =>0

case head :: tail =>1 + length(tail) }

Korrekte Software 58 [66]

(60)

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]

(61)

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]

(62)

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]

(63)

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]

(64)

Regular Expressions

val regex ="""(\d+)(\w+)""".r val myString = ...

val res : String = myStringmatch{ case regex( digits , word)=> digits case _=>"None"

}

Korrekte Software 63 [66]

(65)

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]

(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]

(67)

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]

(68)

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]

(69)

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]

(70)

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]

(71)

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]

(72)

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.

{1n}

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]

(73)

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.

{1n}

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]

(74)

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]

(75)

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]

(76)

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]

(77)

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]

(78)

C0: Ausdrücke und Anweisungen

Aexp a::=N|Loc |a1+a2 |a1a2 |a1a2 |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]

(79)

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]

(80)

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]

(81)

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]

(82)

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]

(83)

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]

(84)

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]

(85)

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]

(86)

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]

(87)

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]

(88)

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:PQ gdw.

P −→Q.

I Wir könnenAzuA0 einschränken (A0A oderA0 −→A), oderB zu B0 vergrößern (B ⊆B0 oderB−→B0), und erhalten |={A0}c{B0}.

Korrekte Software 15 [21]

(89)

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:PQ gdw.

P −→Q.

I Wir könnenAzuA0 einschränken (A0A oderA0 −→A), oder B zu B0 vergrößern (B ⊆B0 oderB−→B0), und erhalten |={A0}c{B0}.

Korrekte Software 15 [21]

(90)

Ü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]

(91)

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]

(92)

Wie wir Floyd-Hoare-Beweise aufschreiben

// {P}

// {P1} x= e ; // {P2} // {P3}

w h i l e ( x< n ) { // {P3x<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,P3x<n−→P4, P3∧ ¬(x <n)−→Q.

Korrekte Software 18 [21]

(93)

Warum Verifikation?

Hier sind Varianten des Fakultätsbeispiels.

Welche sind korrekt?

// {1n}

p = 1 ; c = 1 ;

w h i l e ( c<=n ) { c = c +1;

p = p∗c ; }

// {p=n!}

// {1n}

p = 1 ; c = 1 ;

w h i l e ( c<n ) { c = c +1;

p = p∗c ; }

// {p=n!}

//{1Nn=N}

p = 1 ;

w h i l e (0<n ) { p = p∗n ; n = n−1;

}

//{p=N!}

Korrekte Software 19 [21]

(94)

Eine Handvoll Beispiele

// {y =Y} x= 1 ;

w h i l e ( y != 0 ) { y= y−1;

x= 2∗x ; }

// {x = 2Y}

// {a0b0}

r= b ; q= 0 ;

w h i l e ( b <= r ) { r= r−y ;

q= q +1;

}

// {a=bq+rr <b}

//{0a}

t= 1 ; s= 1 ; i = 0 ;

w h i l e ( s <= a ) { t= t+ 2 ;

s= s+ t ; i = i + 1 ; }

//{i2aa<(i+ 1)2}

Korrekte Software 20 [21]

(95)

Eine Handvoll Beispiele

// {y =Y y0}

x= 1 ;

w h i l e ( y != 0 ) { y= y−1;

x= 2∗x ; }

// {x = 2Y}

// {a0b0}

r= b ; q= 0 ;

w h i l e ( b <= r ) { r= r−y ;

q= q +1;

}

// {a=bq+rr <b}

//{0a}

t= 1 ; s= 1 ; i = 0 ;

w h i l e ( s <= a ) { t= t+ 2 ;

s= s+ t ; i = i + 1 ; }

//{i2aa<(i+ 1)2}

Korrekte Software 20 [21]

(96)

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]

(97)

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]

(98)

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]

(99)

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]

(100)

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]

Referenzen

ÄHNLICHE DOKUMENTE

Korrekte Software: Grundlagen und Methoden Vorlesung 3 vom 11.04.19..

I Für Iterationen wird eine Invariante benötigt (die nicht hergeleitet werden kann).. Korrekte Software

I Die (operationale) Semantik einer imperativen Sprache wie C0 ist ein Zustandsübergang: das System hat einen impliziten Zustand, der durch Zuweisung von Werten an Adressen

I Die (operationale) Semantik einer imperativen Sprache wie C0 ist ein Zustandsübergang: das System hat einen impliziten Zustand, der durch Zuweisung von Werten an Adressen

Zu zeigen ist, dass sowohl w also auch if (b) {c; w} else { } zu dem selben Programmzustand auswerten oder beide zu

Korrekte Software: Grundlagen und Methoden Vorlesung 3 vom 17.04.18: Denotationale Semantik.. Serge Autexier,

Korrekte Software: Grundlagen und Methoden Vorlesung 4 vom 24.04.17: Denotationale Semantik.. Serge Autexier,

[r]