K. Rustan M. Leino Microsoft Research, Redmond NUI Maynooth Maynooth, Ireland 8 June 2007.

24
Program verification via an intermediate language K. Rustan M. Leino Microsoft Research, Redmond NUI Maynooth Maynooth, Ireland 8 June 2007
  • date post

    21-Dec-2015
  • Category

    Documents

  • view

    218
  • download

    1

Transcript of K. Rustan M. Leino Microsoft Research, Redmond NUI Maynooth Maynooth, Ireland 8 June 2007.

Program verification via an intermediate language

K. Rustan M. LeinoMicrosoft Research, Redmond

NUI MaynoothMaynooth, Ireland8 June 2007

CollaboratorsMike BarnettNikolaj BjørnerEvan ChangÁdám DarvasRob DeLineLeo de MouraManuel FähndrichDiego GarbervetskyBart JacobsFrancesco Logozzo

Rosemary MonahanMichaŀ MoskalPeter MüllerMadan MusuvathiDave NaumannSimon OuArnd Poetzsch-HeffterWolfram SchulteHerman VenterAngela Wallenburg…

Grand Challenge of

Verified SoftwareHoare, Joshi, Leavens, Misra, Naumann, Shankar, Woodcock, et al.

“We envision a world in which computer programs are always the most reliable component of any system or device that contains them” [Hoare & Misra]

Spec# programming systemSpec# language

Object-oriented .NET languageMore typesSpecifications (pre- and postconditions, etc.)

Usage rules (methodology)Checking:

Static type checkingRun-time checkingStatic verification (optional)

Static verificationsound modular verificationfocus on automation, not full functional correctness specificationsno termination verificationno verification of temporal properties

Spec# demo

stati

c veri

fier

(Boog

ie)

MSIL (“bytecode”)

SMT solver

V.C. generator

Inference engine

translator

verification condition

“correct” or list of errors

Spec# compiler

Spec#

BoogiePL

Spec# verifier architecture

BoogiePLC Eiffel …Java+JMLSpec#

Simplify

Z3 CVC 3SMT Lib

Coq …

BoogiePL

abstract interpreterpredicate

abstractiontermination detector

BoogiePL declarationstypeconstfunctionaxiomvarprocedureimplementation

BoogiePL statementsx := Ea[ i ] := Ehavoc xassert Eassume E;call P()

ifwhilebreaklabel:goto A, B

While and gotoThe code:

x := 0;while (x < 0)

invariant 0 ≤ x && x ≤ 10;{

x := x + 1;}

is equivalent to:x := 0; goto Head;Head: assert 0 ≤ x && x ≤ 10; goto Body, Done;Body: assume x < 10; x := x + 1; goto Head;Done: assume 10 ≤ x;

Procedure callsGiven:

procedure M();requires P; modifies w; ensures Q;

the code:call M();

is equivalent to:assert P; havoc w; assume Q;

(ignoring old expressions, and not showing parameters)

Example: Dutch flag

Example: source programclass C : object {

int x;C() { … } virtual int M(int n) { … } static void Main() {

C c = new C();c.x = 12;int y = c.M(5);

}}

Example: BoogiePL translation (0)// class typesconst unique System.Object: name;const unique C: name;

axiom C <: System.Object;

function typeof(o: ref) returns (t: name);

// fieldstype field;const unique C.x: field;const unique allocated: field;

// the heapvar Heap: [ref, field] int;

class C: object {

int x;

Example: BoogiePL translation (1)// method declarations

procedure C..ctor(this: ref); requires this != null && typeof(this) <: C; modifies Heap;

procedure C.M(this: ref, n: int) returns (result: int); requires this != null && typeof(this) <: C; modifies Heap;

procedure C.Main(); modifies Heap;

C() { … }

virtual int M(int n)

static void Main()

Example: BoogiePL translation (2)// method implementationsimplementation C.Main(){ var c: ref, y: int;

havoc c; assume c != null; assume Heap[c, allocated] ==

0; assume typeof(c) == C; Heap[c, allocated] := 1; call C..ctor(c);

assert c != null; Heap[c, C.x] := 12;

call y := C.M(c, 5);

}

C c = new C();

c.x = 12;

int y = c.M(5);

Modeling the heapclass C { int f; object g; }var f: [ref] int;var g: [ref] ref;type Field; type Value;var Heap: [ref, Field] Value;function V2I(Value) returns (int);function I2V (int) returns (Value);axiom ( v: Value I2V(V2I(v)) == v);axiom ( i: int V2I(I2V(i)) == i);type Field ;var Heap: ( [ref, Field ] );

x = c.f;

x := f [ c ];x = c.f;

x := V2I(Heap[ c, f ]);

x = c.f;

x := Heap[ c, f ];

Example:Chunker.NextChunk specificationpublic string NextChunk() modifies this.*; ensures result.Length <=

ChunkSize;

Chunker.NextChunk translationprocedure Chunker.NextChunk(this: ref where $IsNotNull(this, Chunker)) returns ($result: ref where $IsNotNull($result, System.String)); // in-parameter: target object free requires $Heap[this, $allocated]; requires ($Heap[this, $ownerFrame] == $PeerGroupPlaceholder || !($Heap[$Heap[this, $ownerRef], $inv] <: $Heap[this, $ownerFrame]) ||

$Heap[$Heap[this, $ownerRef], $localinv] == $BaseClass($Heap[this, $ownerFrame])) && (forall $pc: ref :: $pc != null && $Heap[$pc, $allocated] && $Heap[$pc, $ownerRef] == $Heap[this, $ownerRef] && $Heap[$pc, $ownerFrame] == $Heap[this, $ownerFrame] ==> $Heap[$pc, $inv] == $typeof($pc) && $Heap[$pc, $localinv] == $typeof($pc));

// out-parameter: return value free ensures $Heap[$result, $allocated]; ensures ($Heap[$result, $ownerFrame] == $PeerGroupPlaceholder || !($Heap[$Heap[$result, $ownerRef], $inv] <: $Heap[$result, $ownerFrame]) ||

$Heap[$Heap[$result, $ownerRef], $localinv] == $BaseClass($Heap[$result, $ownerFrame])) && (forall $pc: ref :: $pc != null && $Heap[$pc, $allocated] && $Heap[$pc, $ownerRef] == $Heap[$result, $ownerRef] && $Heap[$pc, $ownerFrame] == $Heap[$result, $ownerFrame] ==> $Heap[$pc, $inv] == $typeof($pc) && $Heap[$pc, $localinv] == $typeof($pc));

// user-declared postconditions ensures $StringLength($result) <= $Heap[this, Chunker.ChunkSize]; // frame condition modifies $Heap; free ensures (forall $o: ref, $f: name :: { $Heap[$o, $f] } $f != $inv && $f != $localinv && $f != $FirstConsistentOwner && (!IsStaticField($f) || !

IsDirectlyModifiableField($f)) && $o != null && old($Heap)[$o, $allocated] && (old($Heap)[$o, $ownerFrame] == $PeerGroupPlaceholder || !(old($Heap)[old($Heap)[$o, $ownerRef], $inv] <: old($Heap)[$o, $ownerFrame]) || old($Heap)[old($Heap)[$o, $ownerRef], $localinv] == $BaseClass(old($Heap)[$o, $ownerFrame])) && old($o != this || !(Chunker <: DeclType($f)) || !$IncludedInModifiesStar($f)) && old($o != this || $f != $exposeVersion) ==> old($Heap)[$o, $f] == $Heap[$o, $f]);

// boilerplate free requires $BeingConstructed == null; free ensures (forall $o: ref :: { $Heap[$o, $localinv] } { $Heap[$o, $inv] } $o != null && !old($Heap)[$o, $allocated] && $Heap[$o, $allocated] ==>

$Heap[$o, $inv] == $typeof($o) && $Heap[$o, $localinv] == $typeof($o)); free ensures (forall $o: ref :: { $Heap[$o, $FirstConsistentOwner] } old($Heap)[old($Heap)[$o, $FirstConsistentOwner], $exposeVersion] ==

$Heap[old($Heap)[$o, $FirstConsistentOwner], $exposeVersion] ==> old($Heap)[$o, $FirstConsistentOwner] == $Heap[$o, $FirstConsistentOwner]);

free ensures (forall $o: ref :: { $Heap[$o, $localinv] } { $Heap[$o, $inv] } old($Heap)[$o, $allocated] ==> old($Heap)[$o, $inv] == $Heap[$o, $inv] && old($Heap)[$o, $localinv] == $Heap[$o, $localinv]);

free ensures (forall $o: ref :: { $Heap[$o, $allocated] } old($Heap)[$o, $allocated] ==> $Heap[$o, $allocated]) && (forall $ot: ref :: { $Heap[$ot, $ownerFrame] } { $Heap[$ot, $ownerRef] } old($Heap)[$ot, $allocated] && old($Heap)[$ot, $ownerFrame] != $PeerGroupPlaceholder ==> old($Heap)[$ot, $ownerRef] == $Heap[$ot, $ownerRef] && old($Heap)[$ot, $ownerFrame] == $Heap[$ot, $ownerFrame]) && old($Heap)[$BeingConstructed, $NonNullFieldsAreInitialized] == $Heap[$BeingConstructed, $NonNullFieldsAreInitialized];

QuantifiersInstantiation via e-graph matchingA matching pattern (trigger) is a set of terms that together mention all the bound variables, and none of which is just a bound variable by itselfExamples:

(x { f(x) } 0 ≤ f(x))(x,y { g(x,y) } f(x) < g(x,y))

More trigger examples(x,y { f(x), f(y) } x ≤ y f(x) ≤ f(y))(x { f(x) } x ≠ null f(x) ≤ f(next(x)))(x { f(next(x)) } x ≠ null f(x) ≤ f(next(x)))(x,y { f(x), f(y) } f(x) = f(y) x = y)(x { f(x) } fInv(f(x)) = x)(x { f(x+1) } f(x) ≤ f(x+1))(x,y,z { x*(y+z) } x*(y+z) = x*y + x*z)(x,y { P(x,y) } x = y P(x,y) = 10)(x { P(x,x) } P(x,x) = 10)

Example: Reverse

Download

Spec# and

Boogie

from here

ConclusionsSpec# is an object-oriented language with

specificationsBoogiePL is an intermediate verification language

Separates concernsEnables sharing in the verification community

front ends for multiple languagesbenchmarksabstract interpretationVC generationmultiple theorem proverspredicate abstraction…

http://research.microsoft.com/specsharp