Presentation is loading. Please wait.

Presentation is loading. Please wait.

K. Rustan M. Leino Principal Researcher Microsoft Research, Redmond, WA, USA 14 Nov 2007 Øredev Malmö, Sweden.

Similar presentations


Presentation on theme: "K. Rustan M. Leino Principal Researcher Microsoft Research, Redmond, WA, USA 14 Nov 2007 Øredev Malmö, Sweden."— Presentation transcript:

1 K. Rustan M. Leino Principal Researcher Microsoft Research, Redmond, WA, USA 14 Nov 2007 Øredev Malmö, Sweden

2 Mike Barnett Nikolaj Bjørner Ádám Darvas Leonardo de Moura Manuel Fähndrich Bart Jacobs Francesco Logozzo Ronald Middelkoop Peter Müller Ralf Sasse Wolfram Schulte Herman Venter Angela Wallenburg

3 Take risks Advance state of the art, state of knowledge Over time, have a significant impact on Microsoft products First “customers”: early adopters

4 What seems useful to you? Email me, leino@microsoft.com or—better yet—the Spec# mailing list, see http://research.microsoft.com/specsharp

5 Problem Building and maintaining programs that are correct Approach Specifications record design decisions bridge intent and code Tools amplify human effort manage details find inconsistencies ensure quality

6 Build the best such system we can build today Experiment with the system to get a feel for what it is like to use Advance the state of the art

7 Spec# language Object-oriented.NET language Superset of C#, adding: more types specifications (pre- and postconditions, etc.) Usage rules (methodology) Checking: Static type checking Run-time checking Static program verification (optional)

8 { P } S { Q } If program S is started in a state satisfying the precondition P, then the execution of S will not go wrong and if the execution terminates, it does so in a state satisfying the postcondition Q If S starts in P, then it ends in Q

9 StringBuilder.Append Method (Char[ ], Int32, Int32) Appends the string representation of a specified subarray of Unicode characters to the end of this instance. public StringBuilder Append(char[] value, int startIndex, int charCount); Parameters value A character array. startIndex The starting position in value. charCount The number of characters append. Return Value A reference to this instance after the append operation has occurred. Exceptions Exception TypeCondition ArgumentNullExceptionvalue is a null reference, and startIndex and charCount are not zero. ArgumentOutOfRangeExceptioncharCount is less than zero. -or- startIndex is less than zero. -or- startIndex + charCount is less than the length of value.

10 public StringBuilder Append(char[] value, int startIndex, int charCount ); requires value == null ==> startIndex == 0 && charCount == 0; requires 0 <= startIndex; requires 0 <= charCount; requires value == null || startIndex + charCount <= value.Length; Exception TypeCondition ArgumentNullExceptionvalue is a null reference, and startIndex and charCount are not zero. ArgumentOutOfRangeExceptioncharCount is less than zero. -or- startIndex is less than zero. -or- startIndex + charCount is less than the length of value.

11 A specification has three parts: requires P;// precondition modifies x;// frame condition ensures Q;// postcondition A specification is a contract between callers and implementions: Caller must establish P before call Implementation can assume P on entry to method Implementation must establish Q before returning, and must only modify x Caller can assume Q holds upon return, and that only x was modified

12

13 dict: :Chunker:Chunker :Dictionary:Dictionary n: 84 Count: 21 :Chunker:Chunker dict: n: 20 inv dict.Count ≤ n; :Classroom:Classroom studentGrades: inv studentGrades.Count ≤ 20; reprep inv dict.Count ≤ n; owner

14 Spec# is superset of C# From C# to Spec#: accept every C# program compile it to have the same behavior Consequences “Possible null dereference” is just a warning “Must initialize non-null fields before calling base constructor” is an error Support for out-of-band contracts

15 class B : A { string! src; public B(string! source, int x) requires 0 <= x; { this.src = source; base(x); }

16 class B : A { string src; public B(string source, int x) //^ requires 0 <= x; :base(x) { this.src = source; //^ base; }

17 Show and tell

18 requires 0 <= startIndex otherwise ArgumentOutOfRangeException; Exception TypeCondition ArgumentNullExceptionvalue is a null reference, and startIndex and charCount are not zero. ArgumentOutOfRangeExceptioncharCount is less than zero. -or- startIndex is less than zero. -or- startIndex + charCount is less than the length of value.

19 type checking, program verification preconditionspreconditions throws clauses Program errors e.g., NullPointerException, ArrayBoundsException Parameter validation e.g., ArgumentException Unanticipated events e.g., OutOfMemoryError, InternalCLRError Anticipated conditions e.g., SocketClosedException

20 Show and tell

21 interface J { void M(int x); requires P; } class A { public abstract void M(int x); requires Q; } class B : A, J { public override void M(int x) { … } }

22 static verifier (Boogie) MSIL (“bytecode”) SMT solver V.C. generator Inference engine Translator verification condition “correct” or list of errors Spec# compiler Spec# BoogiePL

23 public string! NextChunk() modifies this.*; ensures result.Length <= ChunkSize; { string s; if (n + ChunkSize <= src.Length) { s = src.Substring(n, ChunkSize); } else { s = src.Substring(n); } n += s.Length; return s; }

24 (LET ((FORMULA ReallyLastGeneratedExit_correct (IMPLIES (LBLPOS |+25122| TRUE) (AND (LBLNEG |@28448| (OR (EQ (select2 $Heap@7 s@0 $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 $Heap@7 (select2 $Heap@7 s@0 $ownerRef) $inv) (select2 $Heap@7 s@0 $ownerFrame)) |@true|)) (EQ (select2 $Heap@7 (select2 $Heap@7 s@0 $ownerRef) $localinv) ($BaseClass (select2 $Heap@7 s@0 $ownerFrame)))))) (IMPLIES (OR (EQ (select2 $Heap@7 s@0 $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 $Heap@7 (select2 $Heap@7 s@0 $ownerRef) $inv) (select2 $Heap@7 s@0 $ownerFrame)) |@true|)) (EQ (select2 $Heap@7 (select2 $Heap@7 s@0 $ownerRef) $localinv) ($BaseClass (select2 $Heap@7 s@0 $ownerFrame))))) (AND (LBLNEG |@28511| (FORALL ($pc) (PATS ($typeof $pc) (select2 $Heap@7 $pc $localinv) (select2 $Heap@7 $pc $inv) (select2 $Heap@7 $pc $ownerFrame) (select2 $Heap@7 $pc $ownerRef)) (QID unknown.0:0) (SKOLEMID 19) (IMPLIES (AND (AND (NEQ $pc nullObject) (EQ (select2 $Heap@7 $pc $allocated) |@true|)) (AND (EQ (select2 $Heap@7 $pc $ownerRef) (select2 $Heap@7 s@0 $ownerRef)) (EQ (select2 $Heap@7 $pc $ownerFrame) (select2 $Heap@7 s@0 $ownerFrame)))) (AND (EQ (select2 $Heap@7 $pc $inv) ($typeof $pc)) (EQ (select2 $Heap@7 $pc $localinv) ($typeof $pc)))))) (IMPLIES (FORALL ($pc) (PATS ($typeof $pc) (select2 $Heap@7 $pc $localinv) (select2 $Heap@7 $pc $inv) (select2 $Heap@7 $pc $ownerFrame) (select2 $Heap@7 $pc $ownerRef)) (QID unknown.0:0) (SKOLEMID 19) (IMPLIES (AND (AND (NEQ $pc nullObject) (EQ (select2 $Heap@7 $pc $allocated) |@true|)) (AND (EQ (select2 $Heap@7 $pc $ownerRef) (select2 $Heap@7 s@0 $ownerRef)) (EQ (select2 $Heap@7 $pc $ownerFrame) (select2 $Heap@7 s@0 $ownerFrame)))) (AND (EQ (select2 $Heap@7 $pc $inv) ($typeof $pc)) (EQ (select2 $Heap@7 $pc $localinv) ($typeof $pc))))) (AND (LBLNEG |@28647| (<= ($StringLength s@0) (select2 $Heap@7 this Chunker.ChunkSize))) (IMPLIES (<= ($StringLength s@0) (select2 $Heap@7 this Chunker.ChunkSize)) TRUE)))))))) (FORMULA block4437_correct (IMPLIES (LBLPOS |+5747| TRUE) (IMPLIES TRUE (IMPLIES TRUE ReallyLastGeneratedExit_correct)))) (FORMULA block4590_correct (IMPLIES (LBLPOS |+5742| TRUE) (IMPLIES TRUE (IMPLIES TRUE block4437_correct)))) (FORMULA block4607-2-block4590_correct (IMPLIES (LBLPOS |+25365| TRUE) (IMPLIES (EQ $Heap@7 $Heap@6) (IMPLIES (EQ stack0s@1 stack0s@0) (IMPLIES (EQ stack0o@4 stack0o@3) block4590_correct))))) (FORMULA block4607_correct (IMPLIES (LBLPOS |+5573| TRUE) (IMPLIES TRUE (IMPLIES (EQ ($IsTokenForType stack0s@0 Chunker) |@true|) (IMPLIES (EQ stack0o@3 (TypeObject Chunker)) (AND (LBLNEG |@28246| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (AND (LBLNEG |@28252| (EQ (select2 $Heap@5 this $localinv) System.Object)) (IMPLIES (EQ (select2 $Heap@5 this $localinv) System.Object) (AND (LBLNEG |@28263| (< 0 (select2 $Heap@5 this Chunker.ChunkSize))) (IMPLIES (< 0 (select2 $Heap@5 this Chunker.ChunkSize)) (AND (LBLNEG |@28274| (<= 0 (select2 $Heap@5 this Chunker.n))) (IMPLIES (<= 0 (select2 $Heap@5 this Chunker.n)) (AND (LBLNEG |@28285| (<= (select2 $Heap@5 this Chunker.n) ($StringLength (select2 $Heap@5 this Chunker.src)))) (IMPLIES (<= (select2 $Heap@5 this Chunker.n) ($StringLength (select2 $Heap@5 this Chunker.src))) (AND (LBLNEG |@28303| (FORALL ($p) (QID unknown.0:0) (SKOLEMID 55) (IMPLIES (AND (AND (NEQ $p nullObject) (EQ (select2 $Heap@5 $p $allocated) |@true|)) (AND (EQ (select2 $Heap@5 $p $ownerRef) this) (EQ (select2 $Heap@5 $p $ownerFrame) Chunker))) (AND (EQ (select2 $Heap@5 $p $inv) ($typeof $p)) (EQ (select2 $Heap@5 $p $localinv) ($typeof $p)))))) (IMPLIES (FORALL ($p) (QID unknown.0:0) (SKOLEMID 55) (IMPLIES (AND (AND (NEQ $p nullObject) (EQ (select2 $Heap@5 $p $allocated) |@true|)) (AND (EQ (select2 $Heap@5 $p $ownerRef) this) (EQ (select2 $Heap@5 $p $ownerFrame) Chunker))) (AND (EQ (select2 $Heap@5 $p $inv) ($typeof $p)) (EQ (select2 $Heap@5 $p $localinv) ($typeof $p))))) (IMPLIES (EQ $Heap@6 (store2 $Heap@5 this $localinv ($typeof this))) (IMPLIES (EQ (IsHeap $Heap@6) |@true|) (IMPLIES TRUE block4607-2-block4590_correct)))))))))))))))))))) (FORMULA true4471to4607_correct (IMPLIES (LBLPOS |+5569| TRUE) (IMPLIES TRUE (IMPLIES (EQ nullObject nullObject) (IMPLIES TRUE block4607_correct))))) (FORMULA true4505to4607_correct (IMPLIES (LBLPOS |+5733| TRUE) (IMPLIES TRUE (IMPLIES (NEQ ($As nullObject Microsoft.Contracts.ICheckedException) nullObject) (IMPLIES TRUE block4607_correct))))) (FORMULA block4556-2-block4590_correct (IMPLIES (LBLPOS |+25363| TRUE) (IMPLIES (EQ $Heap@7 $Heap@5) (IMPLIES (EQ stack0s@1 stack0s) (IMPLIES (EQ stack0o@4 nullObject) block4590_correct))))) (FORMULA block4556_correct (IMPLIES (LBLPOS |+5737| TRUE) (IMPLIES TRUE (IMPLIES TRUE block4556-2-block4590_correct)))) (FORMULA false4505to4556_correct (IMPLIES (LBLPOS |+5735| TRUE) (IMPLIES TRUE (IMPLIES (EQ ($As nullObject Microsoft.Contracts.ICheckedException) nullObject) (IMPLIES TRUE block4556_correct))))) (FORMULA block4505_correct (IMPLIES (LBLPOS |+5575| TRUE) (IMPLIES TRUE (IMPLIES TRUE (AND true4505to4607_correct false4505to4556_correct))))) (FORMULA false4471to4505_correct (IMPLIES (LBLPOS |+5571| TRUE) (IMPLIES TRUE (IMPLIES (NEQ nullObject nullObject) (IMPLIES TRUE block4505_correct))))) (FORMULA block4471_correct (IMPLIES (LBLPOS |+5554| TRUE) (IMPLIES TRUE (IMPLIES TRUE (AND true4471to4607_correct false4471to4505_correct))))) (FORMULA block4284_correct (IMPLIES (LBLPOS |+5401| TRUE) (IMPLIES TRUE (AND (LBLNEG |@27875| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (IMPLIES (EQ stack0i@2 (select2 $Heap@4 this Chunker.n)) (AND (LBLNEG |@27893| (NEQ s@0 nullObject)) (IMPLIES (NEQ s@0 nullObject) (IMPLIES (EQ stack1i@5 ($StringLength s@0)) (IMPLIES (EQ stack0i@3 (+ stack0i@2 stack1i@5)) (AND (LBLNEG |@27916| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (AND (LBLNEG |@27923| (OR (EQ (select2 $Heap@4 this $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 $Heap@4 (select2 $Heap@4 this $ownerRef) $inv) (select2 $Heap@4 this $ownerFrame)) |@true|)) (EQ (select2 $Heap@4 (select2 $Heap@4 this $ownerRef) $localinv) ($BaseClass (select2 $Heap@4 this $ownerFrame)))))) (IMPLIES (OR (EQ (select2 $Heap@4 this $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 $Heap@4 (select2 $Heap@4 this $ownerRef) $inv) (select2 $Heap@4 this $ownerFrame)) |@true|)) (EQ (select2 $Heap@4 (select2 $Heap@4 this $ownerRef) $localinv) ($BaseClass (select2 $Heap@4 this $ownerFrame))))) (IMPLIES (EQ $Heap@5 (store2 $Heap@4 this Chunker.n stack0i@3)) (AND (LBLNEG |@28007| (OR (NOT (AND (EQ (<: (select2 $Heap@5 this $inv) Chunker) |@true|) (NEQ (select2 $Heap@5 this $localinv) ($BaseClass Chunker)))) (< 0 (select2 $Heap@5 this Chunker.ChunkSize)))) (IMPLIES (OR (NOT (AND (EQ (<: (select2 $Heap@5 this $inv) Chunker) |@true|) (NEQ (select2 $Heap@5 this $localinv) ($BaseClass Chunker)))) (< 0 (select2 $Heap@5 this Chunker.ChunkSize))) (AND (LBLNEG |@28055| (OR (NOT (AND (EQ (<: (select2 $Heap@5 this $inv) Chunker) |@true|) (NEQ (select2 $Heap@5 this $localinv) ($BaseClass Chunker)))) (<= 0 (select2 $Heap@5 this Chunker.n)))) (IMPLIES (OR (NOT (AND (EQ (<: (select2 $Heap@5 this $inv) Chunker) |@true|) (NEQ (select2 $Heap@5 this $localinv) ($BaseClass Chunker)))) (<= 0 (select2 $Heap@5 this Chunker.n))) (AND (LBLNEG |@28103| (OR (NOT (AND (EQ (<: (select2 $Heap@5 this $inv) Chunker) |@true|) (NEQ (select2 $Heap@5 this $localinv) ($BaseClass Chunker)))) (<= (select2 $Heap@5 this Chunker.n) ($StringLength (select2 $Heap@5 this Chunker.src))))) (IMPLIES (OR (NOT (AND $Heap@5 this Chunker.n) ($StringLength (select2 $Heap@5 this Chunker.src)))) (IMPLIES (EQ (IsHeap $Heap@5) |@true|) (IMPLIES TRUE block4471_correct))))))))))))))))))))))) (FORMULA block4267-2-block4284_correct (IMPLIES (LBLPOS |+25361| TRUE) (IMPLIES (EQ stack2i@1 stack2i) (IMPLIES (EQ s@0 call4133formal@$result@0) (IMPLIES (EQ stack1i@4 stack1i@3) (IMPLIES (EQ $ActivityIndicator@2 $ActivityIndicator@1) (IMPLIES (EQ stack0o@2 stack0o@1) (IMPLIES (EQ $Heap@4 $Heap@3) block4284_correct)))))))) (FORMULA block4267_correct (IMPLIES (LBLPOS |+2908| TRUE) (IMPLIES TRUE (AND (LBLNEG |@26919| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (IMPLIES (EQ stack0o@1 (select2 $Heap@1 this Chunker.src)) (AND (LBLNEG |@26937| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (IMPLIES (EQ stack1i@3 (select2 $Heap@1 this Chunker.n)) (AND (LBLNEG |@26955| (NEQ stack0o@1 nullObject)) (IMPLIES (NEQ stack0o@1 nullObject) (IMPLIES (AND (EQ ($IsNotNull call4133formal@$result System.String) |@true|) (EQ (select2 $Heap call4133formal@$result $allocated) |@true|)) (AND (LBLNEG |@26962| (<= 0 stack1i@3)) (IMPLIES (<= 0 stack1i@3) (AND (LBLNEG |@26968| (<= stack1i@3 ($StringLength stack0o@1))) (IMPLIES (<= stack1i@3 ($StringLength stack0o@1)) (AND (LBLNEG |@26976| (FORALL ($pc) (PATS ($typeof $pc) (select2 $Heap@1 $pc $localinv) (select2 $Heap@1 $pc $inv) (select2 $Heap@1 $pc $ownerFrame) (select2 $Heap@1 $pc $ownerRef)) (QID unknown.0:0) (SKOLEMID 27) (IMPLIES (AND (AND (NEQ $pc nullObject) (EQ (select2 $Heap@1 $pc $allocated) |@true|)) (AND (EQ (select2 $Heap@1 $pc $ownerRef) (select2 $Heap@1 stack0o@1 $ownerRef)) (EQ (select2 $Heap@1 $pc $ownerFrame) (select2 $Heap@1 (IMPLIES TRUE block4233_correct))))))))))))) (FORMULA block4063_correct (IMPLIES (LBLPOS |+2515| TRUE) (IMPLIES TRUE (IMPLIES TRUE block4216_correct)))) (FORMULA entry_correct (IMPLIES (LBLPOS |+2512| TRUE) (IMPLIES (EQ (IsHeap $Heap) |@true|) (IMPLIES (AND (EQ ($IsNotNull this Chunker) |@true|) (EQ (select2 $Heap this $allocated) |@true|)) (IMPLIES (AND (EQ ($IsNotNull $result System.String) |@true|) (EQ (select2 $Heap $result $allocated) |@true|)) (IMPLIES (AND (EQ ($Is local2 System.Exception) |@true|) (EQ (select2 $Heap local2 $allocated) |@true|)) (IMPLIES (AND (EQ ($Is s System.String) |@true|) (EQ (select2 $Heap s $allocated) |@true|)) (IMPLIES (AND (EQ ($Is return.value System.String) |@true|) (EQ (select2 $Heap return.value $allocated) |@true|)) (IMPLIES (AND (EQ ($Is SS$Display.Return.Local System.String) |@true|) (EQ (select2 $Heap SS$Display.Return.Local $allocated) |@true|)) (IMPLIES (EQ $PurityAxiomsCanBeAssumed |@true|) (IMPLIES (EQ $BeingConstructed nullObject) (IMPLIES (OR (EQ (select2 $Heap this $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 $Heap (select2 $Heap this $ownerRef) $inv) (select2 $Heap this $ownerFrame)) |@true|)) (EQ (select2 $Heap (select2 $Heap this $ownerRef) $localinv) ($BaseClass (select2 $Heap this $ownerFrame))))) (IMPLIES (FORALL ($pc) (PATS ($typeof $pc) (select2 $Heap $pc $localinv) (select2 $Heap $pc $inv) (select2 $Heap $pc $ownerFrame) (select2 $Heap $pc $ownerRef)) (QID unknown.0:0) (SKOLEMID 18) (IMPLIES (AND (AND (NEQ $pc nullObject) (EQ (select2 $Heap $pc $allocated) |@true|)) (AND (EQ (select2 $Heap $pc $ownerRef) (select2 $Heap this $ownerRef)) (EQ (select2 $Heap $pc $ownerFrame) (select2 $Heap this $ownerFrame)))) (AND (EQ (select2 $Heap $pc $inv) ($typeof $pc)) (EQ (select2 $Heap $pc $localinv) ($typeof $pc))))) (IMPLIES TRUE (IMPLIES TRUE block4063_correct)))))))))))))))) entry_correct)

25 Extend structuring methodologies Improve performance …

26 Download Spec# from here Spec# lets programmers work with contracts type checking run-time checking program verification Hardest challenge: programming methodology that fits common programming idioms and can be handled well by automatic prover Education Try it out! http://research.microsoft.com/specsharp


Download ppt "K. Rustan M. Leino Principal Researcher Microsoft Research, Redmond, WA, USA 14 Nov 2007 Øredev Malmö, Sweden."

Similar presentations


Ads by Google