Specifying and verifying programs in Spec# K. Rustan M. Leino Microsoft Research, Redmond, WA, USA...
-
Upload
john-esmond-bond -
Category
Documents
-
view
217 -
download
0
Transcript of Specifying and verifying programs in Spec# K. Rustan M. Leino Microsoft Research, Redmond, WA, USA...
Specifying and verifying programs in Spec#
K. Rustan M. LeinoMicrosoft Research, Redmond, WA, USA
Invited talk, PSI 2006Novosibirsk, Russia27 June 2006
joint work withMike Barnett, Robert DeLine, Manuel Fähndrich, Wolfram Schulte, Herman Venter,
Bor-Yuh Evan Chang, Ádám Darvas, Bart Jacobs, Daan Leijen, Angela Wallenburg,
Francesco Logozzo, Peter Müller, David A. Naumann, Arnd Poetzsch-Heffter
Software engineering problem
Building and maintaining large systems that are correct
Approach
• Specifications record design decisions– bridge intent and code
• Tools amplify human effort– manage details– find inconsistencies– ensure quality
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
valueA character array.
startIndexThe starting position in value.
charCountThe number of characters append.
Return Value
A reference to this instance after the append operation has occurred.
ExceptionsException Type Condition
ArgumentNullException value is a null reference, and startIndex and charCount are not zero.
ArgumentOutOfRangeException charCount is less than zero.
-or-
startIndex is less than zero.
-or-
startIndex + charCount is less than the length of value.
Specifications today
Specifications in program textpublic 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 Type Condition
ArgumentNullException value is a null reference, and startIndex and charCount are not zero.
ArgumentOutOfRangeException charCount is less than zero.
-or-
startIndex is less than zero.
-or-
startIndex + charCount is less than the length of value.
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#• Experimental mix of contracts and tool
support• Aimed at experienced developers who know
the high cost of testing and maintenance• Superset of C#
– non-null types– pre- and postconditions– object invariants
• Tool support– more type checking– compiler-emitted run-time checks– static program verification
C#contracts
everywhere
type checking
static verification
into the future
run-time checks
degree of checking,effort
familiar
Spec# demo
Verification
0. Program verifier architecture1. Semantics2. Verification-condition generation
0. Basic architecture of a verifier
verification conditiongenerator
theorem prover
verification condition
program with specifications
“correct” or list of errors
Spec# verifier architecture
V.C. generator
automatictheorem prover
verification condition
Spec#
“correct” or list of errors
Spec# compiler
MSIL (“bytecode”)
translator
Boogie PL
inference engine
Spec# program verifier (aka Boogie)
1. Semantics
Program outcomes:– terminate– go wrong– block– diverge
Core language
• x := E– evaluate E and change x to that value
• havoc x– change x to an arbitrary value
• assert E– if E holds, terminate; otherwise, go wrong
• assume E– if E holds, terminate; otherwise, block
• S ; T– execute S, then T
• S [] T or goto A or B;– execute either S or T, choosing blindly– change point of control to block A or block B, choosing
blindly
Example translation: if
Tr[[ if P then S else T end ]]=
Start: goto Then or ElseThen: assume P ;
Tr[[ S ]] ;goto After
Else: assume ¬P ;Tr[[ T ]] ;goto After
After: …
Example translation: loop
Tr[[ while { invariant J } B do S end ]]=
LoopHead: assert J ;goto LoopBody or
AfterLoopLoopBody: assume B ;
Tr[[ S ]] ;goto LoopHead
AfterLoop: assume ¬B ;…
Example translation: partial expressions
• Tr[[ x = a / b ; ]] =assert b ≠ 0 ; x := a / b
• Tr[[ x = (T) y ; ]] = // type cast
assert y = null typeof(y) <: T ;x := y
Example translation: fields of objects
• Tr[[ x = o.f; ]] =assert o ≠ null ;x := Heap[ o, f ]
• Tr[[ o.f = x; ]] =assert o ≠ null ;Heap[ o, f ] := x
x := Select(Heap, (o,f))
Heap := Update(Heap, (o,f), x)
Example translation: call
• Givenprocedure M requires Pre modifies w ensures Post
Tr[[ call M; ]] =assert Pre ;havoc w ;assume Post ;
Example translation: object construction
• Tr[[ x = new C(); ]] =havoc x ;assume x ≠ null;assume Heap[ x, allocated ] =
false;assume typeof(x) = C;Heap[ x, allocated ] := true;Tr[[ call C..ctor(x); ]]
2. Verification-condition generation
• Maps core language into first-order formulas– loops
• Concern about prover performance– redundancy and formula size
wp(S [] T, Q) = wp(S, Q) wp(T, Q)
– goto statements
Verification-condition generation0. passive features: assert, assume, ;1. control flow: goto (no loops)2. state changes: :=, havoc3. loops
Weakest preconditions
• The weakest precondition of a statement S with respect to a predicate Q on the post-state of S, denoted wp(S,Q), is the set of pre-states from which execution:– does not go wrong, and– if it terminates, terminates in Q
VC generation: passive features• wp( assert E, Q ) =
E Q• wp( assume E, Q ) =
E Q • wp( S; T, Q ) =
wp( S, wp( T, Q ))
VC generation: acyclic control flow• For each block A, introduce a variable Aok
with the meaning: Aok is true iffevery program execution starting in the current state from block A does not go wrong
• The verification condition for the program:A: S; goto B or C…
is:( Aok wp( S, Bok Cok ) ) …Aok
VC generation: state changes• Replace definitions and uses of
variables by definitions and uses of different incarnations of the variables
{xx0, yy0} x := E(x,y) x1 := E(x0,y0) {xx1, yy0}
{xx0, yy0} havoc xskip {xx1, yy0}
VC generation: state changes (cont.)Given:
{xx0 ,yy0} S S’ {xx1, yy0} {xx0, yy0} T T’ {xx2, yy0}
then we have: {xx0, yy0} if E(x,y) then S else T end
if E(x0,y0) thenS’ ; x3 := x1
elseT’ ; x3 := x2
end{xx3, yy0}
VC generation: state changes (cont.)
• Replace every assignmentx := E
withassume x = E
VC generation: loops
loop head:
loop body:
assert LoopInv( x ) ;
assume Guard( x ) ;x := …assume
¬Guard( x ) ;
after loop:
VC generation: loops
loop head:
loop body:
assert LoopInv( x ) ;assume LoopInv( x );
assume Guard( x ) ;x := …assume ¬Guard( x
) ;
after loop:
assert P=
assert P ; assume P
VC generation: loops
loop head:
loop body:
assert LoopInv( x ) ;assume LoopInv( x );
assume Guard( x ) ;x := …assume
¬Guard( x ) ;
after loop:
assert LoopInv( x ) ;
assert LoopInv( x ) ;
VC generation: loops
loop head:
loop body:
assume LoopInv( x );
assume Guard( x ) ;x := …assert LoopInv( x );
assume ¬Guard( x ) ;
after loop:
assert LoopInv( x ) ;
havoc x ;
loop target
VC generation: loops
loop head:
loop body:
assume LoopInv( x );
assume Guard( x ) ;x := …assert LoopInv( x );assume false;
assume ¬Guard( x ) ;
after loop:
assert LoopInv( x ) ;
havoc x ;
download Spec#from here
Conclusions• Because of tool support, we’re ready for
programming at the next level of rigor• Current work
– Specification/programming/verification methodology
– Performance– Technology transfer– Engineering effort
• Technology sharing– Teaching– Case studies– BoogiePL as common intermediate logic
http://research.microsoft.com/~leino
http://research.microsoft.com/specsharp