Skip this Video
Download Presentation

Loading in 2 Seconds...

play fullscreen
1 / 26

Spec# - PowerPoint PPT Presentation

  • Uploaded on

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

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about 'Spec#' - fagan

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript


K. Rustan M. Leino

Principal ResearcherMicrosoft Research, Redmond, WA, USA

14 Nov 2007ØredevMalmö, Sweden

  • 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
microsoft research
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
want feedback
Want feedback

What seems useful to you?

Email me, [email protected]

or—better yet—the Spec# mailing list, see

software engineering problem
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
research goals
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
spec programming system
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)
program specifications the academic view
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

specifications net today
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);


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.


specifications in spec
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;

method specifications
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
multi object invariants
Multi-object invariants




n: 84

n: 20

invstudentGrades.Count ≤ 20;

invdict.Count ≤ n;

invdict.Count ≤ n;







Count: 21

c compatibility
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
from spec to c or leveraging wiz bang features of visual studio 2005
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); }

from spec to c or leveraging wiz bang features of visual studio 200516
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; }

c mode
C# mode
  • Show and tell
backward compatibility
Backward compatibility

requires 0 <= startIndex


  • 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


throws clauses

  • Show and tell
inheriting contracts
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) { … }}
spec verifier architecture
Spec# verifier architecture


Spec# compiler

MSIL (“bytecode”)



Inference engine

static verifier (Boogie)

V.C. generator

verification condition

SMT solver

“correct” or list of errors

chunker nextchunk

publicstring! NextChunk()


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;


verification condition
(LET ((FORMULA ReallyLastGeneratedExit_correct (IMPLIES (LBLPOS |+25122| TRUE) (AND (LBLNEG |@28448| (OR (EQ (select2 [email protected] [email protected] $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 [email protected] (select2 [email protected] [email protected] $ownerRef) $inv) (select2 [email protected] [email protected] $ownerFrame)) |@true|)) (EQ (select2 [email protected] (select2 [email protected] [email protected] $ownerRef) $localinv) ($BaseClass (select2 [email protected] [email protected] $ownerFrame)))))) (IMPLIES (OR (EQ (select2 [email protected] [email protected] $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 [email protected] (select2 [email protected] [email protected] $ownerRef) $inv) (select2 [email protected] [email protected] $ownerFrame)) |@true|)) (EQ (select2 [email protected] (select2 [email protected] [email protected] $ownerRef) $localinv) ($BaseClass (select2 [email protected] [email protected] $ownerFrame))))) (AND (LBLNEG |@28511| (FORALL ($pc) (PATS ($typeof $pc) (select2 [email protected] $pc $localinv) (select2 [email protected] $pc $inv) (select2 [email protected] $pc $ownerFrame) (select2 [email protected] $pc $ownerRef)) (QID unknown.0:0) (SKOLEMID 19) (IMPLIES (AND (AND (NEQ $pc nullObject) (EQ (select2 [email protected] $pc $allocated) |@true|)) (AND (EQ (select2 [email protected] $pc $ownerRef) (select2 [email protected] [email protected] $ownerRef)) (EQ (select2 [email protected] $pc $ownerFrame) (select2 [email protected] [email protected] $ownerFrame)))) (AND (EQ (select2 [email protected] $pc $inv) ($typeof $pc)) (EQ (select2 [email protected] $pc $localinv) ($typeof $pc)))))) (IMPLIES (FORALL ($pc) (PATS ($typeof $pc) (select2 [email protected] $pc $localinv) (select2 [email protected] $pc $inv) (select2 [email protected] $pc $ownerFrame) (select2 [email protected] $pc $ownerRef)) (QID unknown.0:0) (SKOLEMID 19) (IMPLIES (AND (AND (NEQ $pc nullObject) (EQ (select2 [email protected] $pc $allocated) |@true|)) (AND (EQ (select2 [email protected] $pc $ownerRef) (select2 [email protected] [email protected] $ownerRef)) (EQ (select2 [email protected] $pc $ownerFrame) (select2 [email protected] [email protected] $ownerFrame)))) (AND (EQ (select2 [email protected] $pc $inv) ($typeof $pc)) (EQ (select2 [email protected] $pc $localinv) ($typeof $pc))))) (AND (LBLNEG |@28647| (<= ($StringLength [email protected]) (select2 [email protected] this Chunker.ChunkSize))) (IMPLIES (<= ($StringLength [email protected]) (select2 [email protected] 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 [email protected] [email protected]) (IMPLIES (EQ [email protected] [email protected]) (IMPLIES (EQ [email protected] [email protected]) block4590_correct))))) (FORMULA block4607_correct (IMPLIES (LBLPOS |+5573| TRUE) (IMPLIES TRUE (IMPLIES (EQ ($IsTokenForType [email protected] Chunker) |@true|) (IMPLIES (EQ [email protected] (TypeObjectChunker)) (AND (LBLNEG |@28246| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (AND (LBLNEG |@28252| (EQ (select2 [email protected] this $localinv) System.Object)) (IMPLIES (EQ (select2 [email protected] this $localinv) System.Object) (AND (LBLNEG |@28263| (< 0 (select2 [email protected] this Chunker.ChunkSize))) (IMPLIES (< 0 (select2 [email protected] this Chunker.ChunkSize)) (AND (LBLNEG |@28274| (<= 0 (select2 [email protected] this Chunker.n))) (IMPLIES (<= 0 (select2 [email protected] this Chunker.n)) (AND (LBLNEG |@28285| (<= (select2 [email protected] this Chunker.n) ($StringLength (select2 [email protected] this Chunker.src)))) (IMPLIES (<= (select2 [email protected] this Chunker.n) ($StringLength (select2 [email protected] this Chunker.src))) (AND (LBLNEG |@28303| (FORALL ($p) (QID unknown.0:0) (SKOLEMID 55) (IMPLIES (AND (AND (NEQ $p nullObject) (EQ (select2 [email protected] $p $allocated) |@true|)) (AND (EQ (select2 [email protected] $p $ownerRef) this) (EQ (select2 [email protected] $p $ownerFrame) Chunker))) (AND (EQ (select2 [email protected] $p $inv) ($typeof $p)) (EQ (select2 [email protected] $p $localinv) ($typeof $p)))))) (IMPLIES (FORALL ($p) (QID unknown.0:0) (SKOLEMID 55) (IMPLIES (AND (AND (NEQ $p nullObject) (EQ (select2 [email protected] $p $allocated) |@true|)) (AND (EQ (select2 [email protected] $p $ownerRef) this) (EQ (select2 [email protected] $p $ownerFrame) Chunker))) (AND (EQ (select2 [email protected] $p $inv) ($typeof $p)) (EQ (select2 [email protected] $p $localinv) ($typeof $p))))) (IMPLIES (EQ [email protected] (store2 [email protected] this $localinv ($typeof this))) (IMPLIES (EQ (IsHeap [email protected]) |@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 [email protected] [email protected]) (IMPLIES (EQ [email protected] stack0s) (IMPLIES (EQ [email protected] 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 [email protected] (select2 [email protected] this Chunker.n)) (AND (LBLNEG |@27893| (NEQ [email protected] nullObject)) (IMPLIES (NEQ [email protected] nullObject) (IMPLIES (EQ [email protected] ($StringLength [email protected])) (IMPLIES (EQ [email protected] (+ [email protected] [email protected])) (AND (LBLNEG |@27916| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (AND (LBLNEG |@27923| (OR (EQ (select2 [email protected] this $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 [email protected] (select2 [email protected] this $ownerRef) $inv) (select2 [email protected] this $ownerFrame)) |@true|)) (EQ (select2 [email protected] (select2 [email protected] this $ownerRef) $localinv) ($BaseClass (select2 [email protected] this $ownerFrame)))))) (IMPLIES (OR (EQ (select2 [email protected] this $ownerFrame) $PeerGroupPlaceholder) (OR (NOT (EQ (<: (select2 [email protected] (select2 [email protected] this $ownerRef) $inv) (select2 [email protected] this $ownerFrame)) |@true|)) (EQ (select2 [email protected] (select2 [email protected] this $ownerRef) $localinv) ($BaseClass (select2 [email protected] this $ownerFrame))))) (IMPLIES (EQ [email protected] (store2 [email protected] this Chunker.n [email protected])) (AND (LBLNEG |@28007| (OR (NOT (AND (EQ (<: (select2 [email protected] this $inv) Chunker) |@true|) (NEQ (select2 [email protected] this $localinv) ($BaseClassChunker)))) (< 0 (select2 [email protected] this Chunker.ChunkSize)))) (IMPLIES (OR (NOT (AND (EQ (<: (select2 [email protected] this $inv) Chunker) |@true|) (NEQ (select2 [email protected] this $localinv) ($BaseClassChunker)))) (< 0 (select2 [email protected] this Chunker.ChunkSize))) (AND (LBLNEG |@28055| (OR (NOT (AND (EQ (<: (select2 [email protected] this $inv) Chunker) |@true|) (NEQ (select2 [email protected] this $localinv) ($BaseClassChunker)))) (<= 0 (select2 [email protected] this Chunker.n)))) (IMPLIES (OR (NOT (AND (EQ (<: (select2 [email protected] this $inv) Chunker) |@true|) (NEQ (select2 [email protected] this $localinv) ($BaseClassChunker)))) (<= 0 (select2 [email protected] this Chunker.n))) (AND (LBLNEG |@28103| (OR (NOT (AND (EQ (<: (select2 [email protected] this $inv) Chunker) |@true|) (NEQ (select2 [email protected] this $localinv) ($BaseClassChunker)))) (<= (select2 [email protected] this Chunker.n) ($StringLength (select2 [email protected] this Chunker.src))))) (IMPLIES (OR (NOT (AND [email protected] this Chunker.n) ($StringLength (select2 [email protected] this Chunker.src)))) (IMPLIES (EQ (IsHeap [email protected]) |@true|) (IMPLIES TRUE block4471_correct))))))))))))))))))))))) (FORMULA block4267-2-block4284_correct (IMPLIES (LBLPOS |+25361| TRUE) (IMPLIES (EQ [email protected] stack2i) (IMPLIES (EQ [email protected] [email protected][email protected]) (IMPLIES (EQ [email protected] [email protected]) (IMPLIES (EQ [email protected] [email protected]) (IMPLIES (EQ [email protected] [email protected]) (IMPLIES (EQ [email protected] [email protected]) block4284_correct)))))))) (FORMULA block4267_correct (IMPLIES (LBLPOS |+2908| TRUE) (IMPLIES TRUE (AND (LBLNEG |@26919| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (IMPLIES (EQ [email protected] (select2 [email protected] this Chunker.src)) (AND (LBLNEG |@26937| (NEQ this nullObject)) (IMPLIES (NEQ this nullObject) (IMPLIES (EQ [email protected] (select2 [email protected] this Chunker.n)) (AND (LBLNEG |@26955| (NEQ [email protected] nullObject)) (IMPLIES (NEQ [email protected] nullObject) (IMPLIES (AND (EQ ($IsNotNull [email protected]$result System.String) |@true|) (EQ (select2 $Heap [email protected]$result $allocated) |@true|)) (AND (LBLNEG |@26962| (<= 0 [email protected])) (IMPLIES (<= 0 [email protected]) (AND (LBLNEG |@26968| (<= [email protected] ($StringLength [email protected]))) (IMPLIES (<= [email protected] ($StringLength [email protected])) (AND (LBLNEG |@26976| (FORALL ($pc) (PATS ($typeof $pc) (select2 [email protected] $pc $localinv) (select2 [email protected] $pc $inv) (select2 [email protected] $pc $ownerFrame) (select2 [email protected] $pc $ownerRef)) (QID unknown.0:0) (SKOLEMID 27) (IMPLIES (AND (AND (NEQ $pc nullObject) (EQ (select2 [email protected] $pc $allocated) |@true|)) (AND (EQ (select2 [email protected] $pc $ownerRef) (select2 [email protected] [email protected] $ownerRef)) (EQ (select2 [email protected] $pc $ownerFrame) (select2 [email protected] (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
further challenges
Further challenges
  • Extend structuring methodologies
  • Improve performance
summary and conclusions
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!

DownloadSpec# from here