1 / 57

Introduction to Spec Programming System

Spec

pink
Télécharger la présentation

Introduction to Spec Programming System

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. Introduction to Spec# Programming System Yossi Peery Advanced SW Tools Seminar TAU Nov 2006

    2. Spec# Spec# = C# + contracts 3 levels of checking static type checking runtime checking program verification Boogie verifier Simplify theorem prover Tool support integrated with MS Visual Studio

    3. Non-null types Each reference type T includes the value null Spec#s type T! contains only references to objects of type T (not null).

    4. Types versus Assertions Without non-null types: Person(string name) requires name != null; With non-null types: Person(string/*^!^*/ name) [Q] What is the difference?

    5. Non-null types are flow-sensitive The non-null type of an expression is flow-sensitive. void Foo(T o) { if (o != null) T! p = o; // OK! } That is, it does not follow uniquely from the declared types of the variables and members mentioned in the expression.

    6. Non-null Fields and Object Creation abstract class C { public C() { this.M(); } public abstract int M(); } class D : C { T! f; D(T! x) : base() { f = x; } public override int M{ return f.g; } }

    7. Non-nullness of Fields Common coding pattern: if (o.f != null) o.f.Foo(); [Q] How can this go wrong?

    8. Non-nullness of Properties Common coding pattern: if (o.P != null) o.P.Foo(); [Q] How can this go wrong?

    9. Fields and Properties For the non-null dataflow analysis, it is assumed that non-nullness of fields and properties is preserved in the absence of intervening heap-modifying operations Property reads are not considered heap-modifying operations This is checked at run time because of the possibility of Data races Impure property getters Array element types cannot be non-null

    10. Contracts today

    11. Preconditions Public virtual void Insert(int index, object value) requires 0 <= index && index <= Count; requires !IsReadOnly && !IsFixedSize; { } Run-time checks are inserted by the compiler to validate that preconditions hold RequiresViolationExecption is the default exception

    12. Otherwise clauses Public virtual void Insert(int index, object value) requires 0 <= index && index <= Count; otherwise ArgumentOutOfRangeException requires !IsReadOnly && !IsFixedSize; otherwise NotSupportedException { } Otherwise clause used to specify what happens when requirements are not met in runtime

    13. Postconditions Public virtual void Insert(int index, object value) ensures Count == old(Count) +1 ensures value == this[index]; ensures Forall { int i in 0 : index; old(this[i]) == this[i] }; ensures Forall { int i in index : old(Count); old(this[i]) == this[i] }; Static verification is attempted first Run-time checks inserted by compiler, when required, to check that preconditions hold EnsuresViolationExecption is the default exception of a postcondition failure

    14. Exceptional Postconditions void ReadToken(ArrayList a) throws EndOfFileException ensures a.Count == old(a.Count) Exceptions that can legally occur can be part of a the method contract Can be used only for exceptions that appear in the throws set Can be used only for checked exceptions

    15. Inheriting contracts Method contracts can be inherited Postconditions can be added No changes allowed for preconditions Interface methods can also have specifications Multiple inheritance raises problem of combining contracts Preconditions can be combined only if they are the same Otherwise, only explicit interface method implementation allowed interface I { void M(int x) requires x <= 10; } interface I { void M(int x) requires x <= 10; } class C : I,J { void I.M(int x) {} void J.M(int x) {} }

    16. 0. When do invariants hold? class Car { int speed; int windResistance; invariant windResistance == K * speed * speed; public Car() { speed = 0; windResistance = 0; } public void SetSpeed(int kmph) { speed = kmph; windResistance = K * speed * speed; }

    17. 0. When do invariants hold? class Car { int speed; int windResistance; invariant windResistance == K * speed * speed; public Car() { speed = 0; windResistance = 0; } public void SetSpeed(int kmph) { speed = kmph; windResistance = K * speed * speed; }

    18. When do invariants hold? class Car { int speed; int windResistance; invariant windResistance == K * speed * speed; public Car() { speed = 0; windResistance = 0; } public void SetSpeed(int kmph) { speed = kmph; P( ); windResistance = K * speed * speed; }

    19. Object states Mutable Object invariant might be violated Field updates are allowed Valid Object invariant holds Field updates not allowed

    20. The heap (the object store)

    21. The heap (the object store)

    22. To mutable and back: expose class Car { int speed; int windResistance; invariant windResistance == K * speed * speed; public void SetSpeed(int kmph) requires this.valid; { expose (this) { speed = kmph; windResistance = K * speed * speed; } }

    23. Summary for simple objects:

    24. Summary for simple objects:

    25. Aggregate objects class Seat { public void Move(int pos) requires this.valid; } class Car { Seat s; public void Adjust(Profile p) requires this.valid ? p.valid; { s.Move(p.SeatPosition); }

    26. Ownership

    27. Ownership domains

    28. Ownership domains

    29. An object is only as valid as its components

    30. Representation (rep) fields class Seat { public void Move(int pos) requires this.Consistent; } class Car { rep Seat s; public void Adjust(Profile p) requires this.Consistent ? p.Consistent; { expose (this) { s.Move(p.SeatPosition); } }

    31. Peer fields and peer validity class Seat { public void Move(int pos) requires this.PeerConsistent; } class Car { rep Seat s; peer Seat s; public void Adjust(Profile p) public void Adjust(Position p) requires this.PeerConsistent ? requires this.PeerConsistent ? p.PeerConsistent; p.PeerConsistent; { { expose (this) { s.Move(p.SeatPosition); s.Move(p.SeatPosition); } } }

    32. Summary for aggregate objects:

    33. Summary for aggregate objects:

    34. Immutable types

    35. Ever-peer-consistent (immutable) objects

    36. Summary for immutable types:

    37. Summary for immutable types:

    38. Immutable is determined from static type (except for object) [Immutable] class C extends B { } [Immutable] allowed on C if either B is [Immutable] or B is object [Immutable] required on C if B is [Immutable]

    39. Subclasses class Car { int speed; invariant 0 = speed; } class LuxuryCar extends Car { Radio r; invariant 6 = r.CDCapacity; }

    40. Owners are pairs To support subclasses with invariants, we change owners to be pairs: (object reference, class frame)

    41. Invariants and subclasses

    42. Summary for subclasses:

    43. Summary for subclasses:

    44. Thank You !

    45. Backup Slides

    46. Static field initialization class C { static S ! s ; static T ! t ; static C() { s = new S(); t = new T(); } }

    47. Additive invariants class Car { int speed; } class LuxuryCar extends Car { Radio r; invariant speed > 60 ? r.SoundBooster=true; overrides void SetSpeed(int kmph) { expose (this) { base.SetSpeed(kmph); if (speed > 60) { } } } }

    48. An additive frame is only as valid as its subclass frames

    49. Summary for additive invariants:

    50. Summary for additive invariants:

    51. Object invariants in Spec# Spec# syntactically checks that invariants are admissible Ownership is specified with the [Owned] attribute We first supported only rep ownership relations peer relationships are often useful too we now use PeerConsistent as the default method precondition owners are set automatically on assignments of rep and peer fields An immutable class/interface is specified with [Immutable] We first supported only additive invariants in Spec# non-additive invariants are easier to work with non-additive expose is now the default implementation restriction: no further expose allowed on an object while a non-additive expose is in progress Additive methods (those that update the additive fields mentioned in additive invariants) require dynamic dispatch and use precondition Consistent

    52. From Spec#... static int Abs(int x) ensures 0 <= x ==> result == x; ensures x < 0 ==> result == -x; { if (x < 0) x = -x; return x; }

    53. via BoogiePL procedure Abs(x$in: int) returns ($result: int); ensures 0 <= x$in ==> $result == x$in; ensures x$in < 0 ==> $result == -x$in; { var x1, x2: int, b: bool; entry: x1 := x$in; b := x < 0; goto t, f; t: assume b; x := -x; goto end; f: assume !b; goto end; end: $result := x; return; }

    54. via BoogiePL-DSA procedure Abs(x$in: int) returns ($result: int); ensures 0 <= x$in ==> $result == x$in; ensures x$in < 0 ==> $result == -x$in; { var x1, x2: int, b: bool; entry: x1 := x$in; b := x1 < 0; goto t, f; t: assume b; x2 := -x1; goto end; f: assume !b; x2 := x1; goto end; end: $result := x2; return; }

    55. via Passive BoogiePL procedure Abs(x$in: int) returns ($result: int); ensures 0 <= x$in ==> $result == x$in; ensures x$in < 0 ==> $result == -x$in; { var x1, x2: int, b: bool; entry: assume x1 == x$in; assume b == x1 < 0; goto t, f; t: assume b; assume x2 == -x1; goto end; f: assume !b; assume x2 == x1; goto end; end: assume $result == x2; return; }

    56. without contracts procedure Abs(x$in: int) returns ($result: int); ensures 0 <= x$in ==> $result == x$in; ensures x$in < 0 ==> $result == -x$in; { var x1, x2: int, b: bool; entry: assume x1 == x$in; assume b == x1 < 0; goto t, f; t: assume b; assume x2 == -x1; goto end; f: assume !b; assume x2 == x1; goto end; end: assume $result == x2; return; }

    57. without contracts procedure Abs(x$in: int) returns ($result: int); { var x1, x2: int, b: bool; entry: assume x1 == x$in; assume b == x1 < 0; goto t, f; t: assume b; assume x2 == -x1; goto end; f: assume !b; assume x2 == x1; goto end; end: assume $result == x2; assert 0 <= x$in ==> $result == x$in; assert x$in < 0 ==> $result == -x$in; return; }

    58. to Logic [M. Barnett, K. R. M. Leino, in preparation] entry && (entry <== (x1 == x$in ==> b == x1 < 0 ==> t && f)) && (t <== (b ==> x2 == -x1 ==> end)) && (f <== (!b ==> x2 == x1 ==> end)) && (end <== ($result == x2 ==> (0 <= x$in ==> $result == x$in) && (x$in < 0 ==> $result == -x$in) && true))

More Related