Upload
kylie-moser
View
215
Download
0
Tags:
Embed Size (px)
Citation preview
The Spec# programming system
K. Rustan M. LeinoMicrosoft Research, Redmond, WA, USA
Lunch seminar, PraxisBath, UK6 Dec 2005
joint work withMike Barnett, Robert DeLine, Manuel Fähndrich, Wolfram Schulte, Herman Venter,
Bor-Yuh Evan Chang, Bart Jacobs, Daan Leijen,
Peter Müller, David A. Naumann
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
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
Some design issues
0. Non-null types1. C# compatibility2. Preconditions3. Object invariants4. Program verifier architecture5. Verification-condition generation
• T x; The value of x is null ora reference to an object whose type is a subtype of T.
• T ! y; The value of y isa reference to an object whose type is a subtype of T,not null.
0. Non-null types
Non-null escape hatch: cast
object o;string s;…string! a = (string!)o;string! b = (!)s;
Comparing against null
public void M( T x ) {if (x == null) {
…} else {
int y = ((!)x).f;…
}}
Comparing against null
public void M( T x ) {if (x == null) {
…} else {
int y = x.f;…
}}
Spec# performs a data-flow analysis to allow this (similar to definite assignment)
Non-null instance fields
class C : B {T ! x;public C(T ! y): base(){
this.x = y;}public override int M() { return
x.f; }}
Is this code type safe?No!
abstract class B {public B()
{ this.M(); } public abstract int M();
}
null dereference
Non-null instance fields
class C : B {T ! x;public C(T ! y){
this.x = y;base();
}public override int M() { return
x.f; }}
Spec# allows x to beassigned before baseconstructor is called.
Static field initialization
class C {…static S ! s ;static T ! t ;static C() {
s = new S(…);t = new T(…);
}}
What if this callre-enters class C?
One design choice: Impose a partial order on classes
In Spec#:• enforce all writes• check that static constructor
assigns to the static non-null fields
• do checking at some reads
• 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
1. C# compatibility
From Spec# to C#or: Leveraging wiz-bang features of Visual Studio 2005
class B : A {string! src;public B(string! source, int x)
requires 0 <= x;{
this.src = source;base(x);
}
From Spec# to C#or: Leveraging wiz-bang features of Visual Studio 2005
class B : A {string! src;public B(string! source, int x)
//^ requires 0 <= x;{
this.src = source;base(x);
}
From Spec# to C#or: Leveraging wiz-bang features of Visual Studio 2005
class B : A {string/*!*/ src;public B(string/*!*/ source, int x)
//^ requires 0 <= x;{
this.src = source;base(x);
}
From Spec# to C#or: Leveraging wiz-bang features of Visual Studio 2005
class B : A {string/*!*/ src;public B(string/*!*/ source, int x)
//^ requires 0 <= x; : base(x){
this.src = source;//^ base;
}
2. Preconditions
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.
Contracts today
Contract in Spec#
public StringBuilder Append( char[ ] value, int startIndex,
int charCount ); requires 0 <= startIndex; …
Otherwise clauses
public StringBuilder Append( char[ ] value, int startIndex,
int charCount ); requires 0 <= startIndex otherwise ArgumentOutOfRangeException; …
Inheriting contracts
• 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){ … }
}
3. Object invariants
When do object invariants hold?
class C {private int x;private int y;invariant x < y;
public C() { x = 0; y = 1; }
public void M(){
int t = 100 / (y – x);x = x + 1;P(t);y = y + 1;
}…
}
invariant assumed to holdon entry to method
invariant checked to holdon exit from method
invariant checked to holdat end of constructor
invariant may betemporarily broken here
invariant is restored here
what if P calls back into M?
Object states
• Mutable– Object invariant may not hold– Field updates allowed
• Valid– Object invariant holds– Field updates not allowed
Valid vs. mutable objectsclass C {
private int x;private int y;invariant x < y;
public void M()requires this.inv == Valid;
{expose (this) {
x = x + 1;P(…);y = y + 1;
}}…
}
represent explicitlythat invariant holds(without revealing
what the invariant is)
change this.invfrom Valid to Mutable
check invariant;then, change this.invfrom Mutable to Valid
field updates allowedonly on Mutable objects
Summary of object invariants
• invariant …• inv : { Mutable, Valid }• expose• updates of o.f require o.inv =
Mutable
• (o ・ o.inv = Mutable Inv (o))
4. 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)
BoogiePL
• Intermediate language• Semantics of Spec# is encoded in
BoogiePL• Can be used for other program-
verification tasks, like other source languages
Analyzing verification conditions• Automatic theorem prover
– can be hidden from programmer– generates counterexamples
• Interactive theorem prover– requires gurus– not limited by built-in decision
procedures
5. Verification conditions
• Generate verification conditions that the theorem prover can handle quickly
• We use a new linear technique
VC generation: example
B
E
F
C D
(Aok wp(Body_A, Bok Fok ) (Bok wp(Body_B, Cok Dok ) (Cok wp(Body_C, Eok ) (Dok wp(Body_D, Eok ) (Eok wp(Body_E, Fok ) (Fok wp(Body_F, true ) Aok
Linear technique:
A
download Spec#from here
Conclusions• Because of tool support, we’re ready for
programming at the next level of rigor• Some ingredients
– language design, program semantics, specification techniques, inference algorithms, decision procedures, …
• Methodology is underdeveloped– “Can programming theory yet fully explain
why real big programs work?”– programming theory has not kept up with
practicehttp://research.microsoft.com/~leino
http://research.microsoft.com/specsharp