hwu-logo.png 1 class Rational { 2 int numerator ; int denominator ; 4 public Rational ( int numerator, int denominator ) {

Similar documents
Code Contracts in C#

Code Contracts. Pavel Parízek. CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics

A case study of delegates and generics in C#

MSO Lecture Design by Contract"

Assertions & Design-by-Contract using JML Erik Poll University of Nijmegen

Motivation. Reflection in C# Case study: Implicit Serialisation. Using implicit serialisation. Hans-Wolfgang Loidl

13a. Code Contracts. Overview

Formal Methods for Java

Assertions, pre/postconditions

Advances in Programming Languages

References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 10/14/2004 1

CMSC 433 Section 0101 Fall 2012 Midterm Exam #1

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Assertions. Assertions - Example

C# Data Manipulation

Software Engineering

Testing, Debugging, and Verification

C# Fundamentals. Hans-Wolfgang Loidl School of Mathematical and Computer Sciences, Heriot-Watt University, Edinburgh

C# Threading. Hans-Wolfgang Loidl School of Mathematical and Computer Sciences, Heriot-Watt University, Edinburgh

C# Data Manipulation

Chapter 4 Defining Classes I

Assignment 2 (Solution)

CSC Advanced Object Oriented Programming, Spring Specification

Lecture Notes: Hoare Logic

Software Engineering Testing and Debugging Testing

JML Class Specifications The Java Modeling Language (Part 2) A Java Class

The Java Modeling Language (Part 2)

Advances in Programming Languages

Lecture 10 Design by Contract

Checking Program Properties with ESC/Java

Why Design by Contract! CS 619 Introduction to OO Design and Development. Design by Contract. Fall 2012

Contract Programming For C++0x

Programming with Contracts. Juan Pablo Galeotti, Alessandra Gorla Saarland University, Germany

Program Verification (6EC version only)

Assignment 2 - Specifications and Modeling

Motivation. Correct and maintainable software Cost effective software production Implicit assumptions easily broken

An Annotated Language

Type Hierarchy. Comp-303 : Programming Techniques Lecture 9. Alexandre Denault Computer Science McGill University Winter 2004

Proof Carrying Code(PCC)

Lecture 1 Contracts : Principles of Imperative Computation (Fall 2018) Frank Pfenning

Overview The Java Modeling Language (Part 1) Related Work

n Specifying what each method does q Specify it in a comment before method's header n Precondition q Caller obligation n Postcondition

Advances in Programming Languages

6. Hoare Logic and Weakest Preconditions

Verification Condition Generation

Static program checking and verification

Exceptions and assertions

JML tool-supported specification for Java Erik Poll Radboud University Nijmegen

Formale Entwicklung objektorientierter Software

Part II. Hoare Logic and Program Verification. Why specify programs? Specification and Verification. Code Verification. Why verify programs?

Induction and Semantics in Dafny

CSE 331 Software Design & Implementation

Outline. Introduction. 2 Proof of Correctness. 3 Final Notes. Precondition P 1 : Inputs include

Lectures 20, 21: Axiomatic Semantics

Integrating verification in programming languages

Lecture 1 Contracts. 1 A Mysterious Program : Principles of Imperative Computation (Spring 2018) Frank Pfenning

C#: advanced object-oriented features

Warm-Up Problem. 1. What is the definition of a Hoare triple satisfying partial correctness? 2. Recall the rule for assignment: x (assignment)

Type Checking in COOL (II) Lecture 10

Semantic Analysis. CSE 307 Principles of Programming Languages Stony Brook University

Proof-Carrying-Code. Hans-Wolfgang Loidl

Semantics. There is no single widely acceptable notation or formalism for describing semantics Operational Semantics

Spark verification features

Overview. Probabilistic Programming. Dijkstra s guarded command language: Syntax. Elementary pgcl ingredients. Lecture #4: Probabilistic GCL

Lecture 5 - Axiomatic semantics

Fundamentals of Software Engineering

Exercise 3 Subtyping and Behavioral Subtyping October 13, 2017

The Java Modeling Language JML

Introduction to Linked Lists. Introduction to Recursion Search Algorithms CS 311 Data Structures and Algorithms

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

Formal Specification and Verification

Self-checking software insert specifications about the intent of a system

Reasoning About Imperative Programs. COS 441 Slides 10

Softwaretechnik. Lecture 08: Testing and Debugging Overview. Peter Thiemann SS University of Freiburg, Germany

Specification of a transacted memory for smart cards in Java and JML

Java Modelling Language (JML) References

Softwaretechnik. Lecture 08: Testing and Debugging Overview. Peter Thiemann SS University of Freiburg, Germany

Runtime Checking for Program Verification Systems

CodeContracts: Specification & Verification for the working programmer. Francesco Logozzo joint work with M. Barnett and M.

Hoare logic. A proof system for separation logic. Introduction. Separation logic

Error Handling in C++

Exploring Code with Microsoft Pex

Dynamic Analysis Techniques Part 2

Fortgeschrittene objektorientierte Programmierung (Advanced Object-Oriented Programming)

Proof-Carrying-Code. Authentication for Mobile Code. Motivation. Certificate Size Size of the TCB Performance. Encoding Proofs Program Logics TCB Size

Hoare Logic: Proving Programs Correct

INSTRUCTIONS TO CANDIDATES

Formal Verification Techniques for GPU Kernels Lecture 1

CSE 331 Final Exam 12/14/15 Sample Solution. Question 1. (20 points, 1 each) Warmup. For each statement, circle T if it is true and F if it is false.

Abstract Interpretation

Agenda. More on the Unified Modeling Language. UML diagram types. Packages

Advanced JML Erik Poll Radboud University Nijmegen

CS558 Programming Languages

double d0, d1, d2, d3; double * dp = new double[4]; double da[4];

Javadoc. Computer Science and Engineering College of Engineering The Ohio State University. Lecture 7

Hoare Logic. COMP2600 Formal Methods for Software Engineering. Rajeev Goré

Exception Safety. CS 311 Data Structures and Algorithms Lecture Slides Wednesday, October 28, Glenn G. Chappell. continued

Formal Specification and Verification

Principles of Programming Languages

JML and Aspects: The Benefits of

Transcription:

Code Contracts in C# Hans-Wolfgang Loidl <hwloidl@macs.hw.ac.uk> School of Mathematical and Computer Sciences, Heriot-Watt University, Edinburgh Semester 1 2017/18 Motivation Debugging programs is time-consuming and therefore expensive: As a tester you need to make sure to cover all control-flow paths You should test the program with a wide range of input data You need to test the behaviour with corner cases, e.g. empty string Systematic testing can help with that (see the guest lecture on Systematic Testing by Murray Crease from ScottLogic later in the course) But still, you can t be sure to cover all possible cases. For that, methods of program verification are superior. H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 1 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 2 / 25 Code Contracts Code Contracts are a set of libraries, together with tools to establish properties of your program. Code Contracts allow you to express preconditions postconditions object invariants in your code for runtime checking static analysis documentation A Simple Example 1 class Rational { 2 int numerator ; int denominator ; 3 4 public Rational ( int numerator, int denominator ) { 5 Contract. Requires ( denominator!= 0 ); // pre - condition! 6 this. numerator = numerator ; 7 this. denominator = denominator ; 8 } 9 10 public int Denominator { 11 get { 12 Contract. Ensures ( Contract. Result < int >()!= 0 ); // post - condition 13 return this. denominator ; 14 } 15 } H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 3 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 4 / 25

A Simple Example (cont d) Discussion 1 [ ContractInvariantMethod ] 2 void ObjectInvariant () { // invariant 3 Contract. Invariant ( this. denominator!= 0 ); 4 } With static checking enabled, the IDE will report an error for the call below: Rational badrat = new Rational(3,0); The code defines a class for rational numbers. Semantic side-condition: the denominator must be non-zero. We express this as a precondition in the constructor using Contract.Requires (line 5). Every Rational object must have a non-zero denominator. We express this by an ObjectInvariant method tagged with a [ContractInvariantMethod] attribute. It uses the method call Contract.Invariant to check for a non-zero denominator (line 3). Contract.Ensures expresss a postcondition: the getter Denominator always returns non-zero. 0 See RationalsWithCodeContracts.cs H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 5 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 6 / 25 Preconditions Definition (Precondition) Preconditions are contracts on the state of the world when a method is invoked. Preconditions are expressed using Contract.Requires (...). They generally are used to specify valid parameter values. All members mentioned in preconditions must be at least as accessible as the method itself Otherwise, the precondition cannot be understood (and thus satisfied) by all callers of a method. The condition should also be side-effect free Precondition Example 1 Contract. Requires ( x!= null ); The above precondition expresses that parameter x must be non-null. If your code must throw a particular exception on failure of a particular precondition, you can use the generic overloaded form below. 1 Contract. Requires < ArgumentNullException >( x!= null, "x" ); H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 7 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 8 / 25

Postconditions Postcondition Example Definition (Postcondition) Postconditions are contracts on the state of a method when it terminates. The condition is checked just prior to exiting a method. Unlike preconditions, members with less visibility may be mentioned in a postcondition. A client may not be able to understand or make use of some of the information expressed by a postcondition using private state, but it doesn t affect the client s ability to use the API correctly. 1 Contract. Ensures ( this.f > 0 ); Normal postconditions are expressed using Contract.Ensures (...). They express a condition that must hold on normal termination of the method. 1 Contract. EnsuresOnThrow <T >( this. F > 0 ); Postconditions that should hold when particular exceptions escape from a method, are specified using Contract.EnsuresOnThrow. The condition must hold whenever an exception is thrown that is a subtype of T. H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 9 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 10 / 25 Special Methods within Postconditions Method Return Values: Within postconditions the method s return value can be referred as Contract.Result<T>() (T... return type) Pre-state Values (OldValue): Within a postcondition, an old expression refers to the value of an expression from the pre-state, using Contract.OldValue<T>(e) (T... type of e). Out Parameters: Because contracts appear before the body of the method, most compilers do not allow references to out parameters in postconditions. To get around this issue, the library provides the method Contract.ValueAtReturn<T>(out T t) which will not require that the parameter is already defined. H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 11 / 25 Object Invariants Definition (Invariants) Object invariants are conditions that should hold on each instance of a class whenever that object is visible to a client. They express the conditions under which the object is in a good state. All object s invariants must be in one private nullary instance method containing only Contract.Invariant These methods are identified by being marked with the attribute [ContractInvariantMethod] 1 [ ContractInvariantMethod ] 2 private void ObjectInvariant () { 3 Contract. Invariant ( this.y >= 0); 4 Contract. Invariant ( this.x > this.y); 5... 6 } H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 12 / 25

Assertions Assume Definition (Assertions) Assertions are contracts on the state of the world at an arbitrary point in the program. Assertions are specified using Contract.Assert. They are used to state a condition that must hold at that program point. 1 Contract. Assert ( this. privatefield > 0); 2 Contract. Assert ( this.x == 3, " Why isn t the value of x 3?"); Definition (Assumptions) Assumptions are properties that are expected to be true. Assumptions are specified using Contract.Assume. These are properties that are expected to be true without checking them. 1 Contract. Assume ( this. privatefield > 0); 2 Contract. Assume ( this.x == 3, " Static checker assumed this "); H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 13 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 14 / 25 Quantifiers Code contracts support a limited form of quantifiers: the mathematical quantifier as Contract.ForAll the mathematical quantifier as Contract.Exists The usage of these is limited to what can be computed efficiently. H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 15 / 25 Quantifier Examples 1 public int Foo <T >( IEnumerable <T> xs){ 2 Contract. Requires ( 3 Contract. ForAll (xs, x => x!= null ) ); 4 foreach ( var x in xs) 5... 6 } This example of a contract says that all elements contained in the parameter xs must be non-null. 1 public int [] Bar (){ 2... 3 Contract. Ensures ( 4 Contract. ForAll (0, Contract. Result < int [] >(). Length, 5 index => Contract. Result < int [] >() [ index ] > 0)); This method has a postcondition that all returned values in the array must be positive (could use LINQ s Enumerable.All instead.) H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 16 / 25

Enabling Code Contracts in Visual Studio Another Example: index lookup Our early Get example of a function for returning the n-th element of a data-structure with an indexer only works if the index is less than the array length, now specified as a pre-condition using a code contract: 1 static int Get ( int [] arr, int n) { 2 Contract. Requires (n < arr. Length ); 3 return arr [n]; 4 } If we define data structures in the main code like this: 1 static void Main () { 2 int [] arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 3 int good_ n = 3; /* OK index */ 4 int bad_ n = 15; /* illegal index */ the following call will generate an error in the IDE (if static checking is enabled): Get(arr, bad_n) H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 17 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 18 / 25 Summary Appendix: Basics of Program Logics Code Contracts are a systematic way to test properties of your program, either at compile-time or at run-time. If enabled, the properties will be checked at run-time, raising an exception if it s wrong. If enabled, some properties can be checked at compile-time, giving an error message in the IDE. If none of the above is enabled, there is no performance penalty for having code contracts in your code. You should use in particular pre- and post-conditions for methods to specify correct behaviour. A Hoare-style logic is a formalism to reason about the correctness of programs. In Hoare-style logics we write: {P}e{Q} This should be read as if the property P holds before the execution of the program e, then the property Q holds after executing e Example: Specification of an exponential function {0 y x = X y = Y } exp(x, y) {r = X Y } Note: X, Y are auxiliary variables and must not appear in e H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 19 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 20 / 25

A Simple while-language Language: e ::= skip x := t e 1 ;e 2 if b then e 1 else e 2 while b do e call A judgement has this form (for now!) A Simple Hoare-style Logic {P} skip {P} (skip) {P} e 1 {R} {λz s. P z s[t/x]} x := t {P} (assign) {R} e 2 {Q} {P} e 1 ;e 2 {Q} (comp) {λz s. P z s b s} e 1 {Q} {λz s. P z s (b s)} e 2 {Q} (if) {P} if b then e 1 else e 2 {Q} {P} e {Q} A judgement is valid if the following holds z s t. s e t P z s Q z t {λz s. P z s b s} e {P} {P} while b do e{λz s. P z s (b s)} {P} body {Q} {P} CALL {Q} (while) (call) H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 21 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 22 / 25 A Simple Hoare-style Logic (structural rules) Recursive Functions The consequence rule allows us to weaken the pre-condition and to strengthen the post-condition: s t. ( z. P z s P z s) {P } e {Q } s t. ( z. Q z s Q z s) {P} e {Q} (conseq) In order to deal with recursive functions, we need to collect the knowledge about the behaviour of the functions. We extend the judgement with a context Γ, mapping expressions to Hoare-Triples: Γ {P} e {Q} where Γ has the form {..., (P, e, Q ),...}. H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 23 / 25 H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 24 / 25

Recursive Functions Now, the call rule for recursive, parameter-less functions looks like this: Γ {(P, CALL, Q)} {P} body {Q} Γ {P} CALL {Q} (call) We collect the knowledge about the (one) function in the context, and prove the body. Note: This is a rule for partial correctness: for total correctness we need some form of measure. H-W. Loidl (Heriot-Watt Univ) F20SC/F21SC 2017/18 Code Contracts in C# 25 / 25