1 / 26

Spec#

Spec#. K. Rustan M. Leino Principal Researcher Microsoft Research, Redmond, WA, USA. 14 Nov 2007 Øredev Malm ö, Sweden. Collaborators. Mike Barnett Nikolaj Bjørner Ádám Darvas Leonardo de Moura Manuel F ä hndrich Bart Jacobs Francesco Logozzo. Ronald Middelkoop Peter Müller

fagan
Download Presentation

Spec#

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Spec# K. Rustan M. Leino Principal ResearcherMicrosoft Research, Redmond, WA, USA 14 Nov 2007ØredevMalmö, Sweden

  2. Collaborators • 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. Microsoft Research • Take risks • Advance state of the art, state of knowledge • Over time, have a significant impact on Microsoft products • First “customers”: early adopters

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

  5. Software engineering problem • 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. Research goals • 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# programming system • 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. Program specifications– the academic view { 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. Specifications: .NET today StringBuilder.Append Method (Char[], Int32, Int32) Appends the string representation of a specified subarray of Unicode characters to the end of this instance. publicStringBuilderAppend(char[] value, intstartIndex, intcharCount); 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

  10. Specifications in Spec# publicStringBuilderAppend(char[] value, intstartIndex,intcharCount ); requires value == null ==> startIndex == 0 && charCount == 0; requires0 <= startIndex; requires 0 <= charCount; requires value == null ||startIndex + charCount <= value.Length;

  11. Method specifications • A specification has three parts: requires P; // preconditionmodifies x; // frame conditionensures 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. Spec# demo

  13. Multi-object invariants :Chunker :Chunker :Classroom n: 84 n: 20 invstudentGrades.Count ≤ 20; invdict.Count ≤ n; invdict.Count ≤ n; rep dict: dict: studentGrades: owner :Dictionary Count: 21

  14. C# compatibility • 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. From Spec# to C#or: Leveraging wiz-bang features of Visual Studio 2005 class B : A {string! src;public B(string! source, intx)requires0 <= x; {this.src = source;base(x); }

  16. From Spec# to C#or: Leveraging wiz-bang features of Visual Studio 2005 class B : A {stringsrc;publicB(stringsource, intx) //^ requires 0 <= x; : base(x) {this.src = source;//^ base; }

  17. C# mode • Show and tell

  18. Backward compatibility requires 0 <= startIndex otherwiseArgumentOutOfRangeException;

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

  20. Exceptions • Show and tell

  21. Inheriting contracts • interface J {void M(int x); requires P;} • class A {publicabstractvoid M(int x); requires Q;} • class B : A, J {publicoverridevoid M(int x) { … }}

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

  23. Chunker.NextChunk publicstring! NextChunk() modifiesthis.*; ensuresresult.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 (TypeObjectChunker)) (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 nullObjectnullObject) (IMPLIES TRUE block4607_correct))))) (FORMULA true4505to4607_correct (IMPLIES (LBLPOS |+5733| TRUE) (IMPLIES TRUE (IMPLIES (NEQ ($As nullObjectMicrosoft.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 nullObjectMicrosoft.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 nullObjectnullObject) (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) ($BaseClassChunker)))) (< 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) ($BaseClassChunker)))) (< 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) ($BaseClassChunker)))) (<= 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) ($BaseClassChunker)))) (<= 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) ($BaseClassChunker)))) (<= (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.valueSystem.String) |@true|) (EQ (select2 $Heap return.value $allocated) |@true|)) (IMPLIES (AND (EQ ($Is SS$Display.Return.LocalSystem.String) |@true|) (EQ (select2 $Heap SS$Display.Return.Local $allocated) |@true|)) (IMPLIES (EQ $PurityAxiomsCanBeAssumed |@true|) (IMPLIES (EQ $BeingConstructednullObject) (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) Verification condition

  25. Further challenges • Extend structuring methodologies • Improve performance • …

  26. Summary and conclusions • 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 DownloadSpec# from here

More Related