310 likes | 486 Views
Design by Contract. Invariants Pre-post conditions : Rights and Obligations Exceptions : Contract Violations. Correctness. Implementation is correct relative to a specification. { P } S { Q } Precondition binds the client.
E N D
Design by Contract Invariants Pre-post conditions : Rights and Obligations Exceptions : Contract Violations L10DC
Correctness • Implementation is correctrelative to a specification. { P } S { Q } • Precondition binds the client. • It is an obligation for the client and a benefit for the supplier. • Postcondition binds the supplier (routine). • It is an obligation for the supplier and a benefit for the client. Non-Redundancy Principle L10DC
Spec: pre: x=0 /\ y=3 post: x=3 /\ y=0 Implementations x := 3; y := 0 x :=x+y; y:=x*y t=x; x=y; y=t; Spec? pre: true post: x*x = 2 Spec pre: e > 0 post: x*x -2 < e Spec vs Impl L10DC
Insertion Sort (define (insertion-sort lon) (if (null? lon) () (insert (car lon) (insertion-sort (cdr lon)) ) ) ) // car = first/head, cdr = rest/tail (insertion-sort '(2 3 1 4 7 5) ) = (1 2 3 4 5 7) L10DC
(define (insert n lon) (cond ((null? lon) (list n)) ((> n (car lon)) (cons (car lon) (insert n (cdr lon)) ) ) (else (cons n lon)) )) • Precondition : lon is ordered. • Postcondition : (insert n lon) is ordered. L10DC
Assertions • In theory, assertions are first-order logic formulae. • In a programming language, assertions are computable boolean expressions that can contain program variables, arithmetic/boolean operations, and possibly, user-defined functions. L10DC
(cont’d) • In Eiffel, the expression OLD attr in postcondition denotes the value of the attribute attr on routine entry. • In general, the preconditions must not use features hidden from the clients. However, the postconditions can use any feature, even though only clauses without hidden features are directly usable by the client. L10DC
ADT GStack create: -> GStack push: Gstack x G -> GStack pop: Gstack -> GStack top: GStack -> G empty: Gstack -> boolean constructors: create, push observers: top, empty non-constructors: pop L10DC
ForallseGStack, xeG: pop(push(s,x)) = s top(push(s,x)) = x empty(create()) = true empty(push(s,x)) = false Preconditions: pop(s) requiress=/= create() top(s) requiress=/= create() L10DC
ADT (Bounded) GStack create: int -> GStack push: Gstack x G -> GStack pop: Gstack -> GStack top: GStack -> G empty: Gstack -> boolean full: Gstack -> boolean constructors: create, push observers: top, empty, full non-constructors: pop L10DC
Auxiliary functions: ForallseGstack Terms: neint, xeG: n>0 : count(create(n)) = 0 count(push(s,x)) = 1 + count(s) capacity(create(n)) = n capacity(push(s,x)) = capacity(s) L10DC
Preconditions: ForallseGstack Terms, neint, xeG: n>0 : pop(s) requiress=/= create(n) top(s) requiress=/= create(n) push(s,x) requires capacity(s) >= count(s) + 1 L10DC
ForallseGStack, neint, xeG: n>0 : pop(push(s,x)) = s top(push(s,x)) = x empty(create(n)) = true empty(push(s,x)) = false full(s) = (capacity(s) = count(s)) L10DC
Specifying Class L10DC
Categories of Operations • Creators ( …x … -> T ) • Constructors • Queries (…xTx … -> …) • Observers • Commands (…xTx … -> T ) • Constructors, Non-constructors L10DC
class IntStack { private int capacity ; private int count; public IntStack(int c) { ... // require: c >=0 // ensure: capacity = c // ensure: empty() // ensure: count = 0 } public void push(int e) { ... // require: not full() // ensure: top() = e // ensure: not empty() // ensure: count = old count + 1 } L10DC
public void pop() {... // require: not empty() // ensure: not full() // ensure: count = old count - 1 } public int top() {... // require: not empty() } public boolean empty() {...} public boolean full() {...} // class invariants: // empty() = (count = 0) // full() = (count = capacity) // pop(push(e)) = identity-map } L10DC
Class Invariant • A class invariant for C is a set of assertions that every instance of C must satisfy at all “stable” times. That is, immediately after its creation and before/after a public method call (by a client). • The class invariant relates attributes and/or functions. • E.g., 0 <= count <= capacity • E.g.,(count > 0) => (s[count] = top()) L10DC
Role of Class Invariants in Software Engineering • Invariants not only apply to the routines actually written in the class, but also to any routines added later. • Correctness of a method meth {P and Inv} meth_body {Q and Inv} • Role of constructor definitions If default initialization of the fields violates class invariant, an explicit constructor is needed. L10DC
From ADT specs to Pre-Post Conditions • A precondition for a specs’ function reappears as a precondition for the corresponding routine. • Axioms involving a command (possibly with queries) reappear as postconditions of the corresponding procedure. L10DC
(cont’d) • Axioms involving only queries reappear as postconditions of the corresponding functions or as clauses of the classinvariant. • Axioms involving a creator reappear in the postcondition of the corresponding constructor procedure. L10DC
Introducing Representation class IntStack { private int[] s ; ... public IntStack(int c) { ... // ensure: s =/= null }; public void push(int e) { ... // ensure: s[count] = e // ensure: for i in [1..count-1] do // s[i] = old s[i] }; public void pop() { ... // ensure: for i in [1..count-1] do // s[i] = old s[i] }; ... } //--FRAME AXIOMS--// L10DC
Model-based Spec. and Impl. • Implementation/Representation invariant Assertion characterizing the set of concrete objects that are implementations of the abstract objects (cf. class invariant). • Abstraction function Maps a concrete object (satisfying representation invariant) to the corresponding abstract object. • Usually onto but not one-one. L10DC
“Bugs” • A run-time assertion violation is a manifestation of a bug in the software. • Precondition violation : Bug in the client. • Postcondition violation : Bug in the supplier. • Error • A wrong decision made during software development. • Defect • The property of a software that may cause the system to depart from its intended behavior. • Fault • The event of a software departing from its intended behavior. L10DC
Failure • A routine call failsif it terminates its execution in a state that does not satisfy the routine’s contract. • Violates postcondition or class invariant. • Calls a routine whose precondition is violated. • Causes an abnormal OS signal such as arithmetic overflow, memory exhaustion, etc. L10DC
Exception • An exception is a run-time event that may cause a routine call to fail. • Every failure results from an exception, but not every exception results in a failure (if the routine can recover from it). L10DC
Disciplined Exception Handling • Rescue Clause • Retry • Attempt to change the conditions that led to the exception and execute the routine again from the start (possibly, exploring alternatives). • Software fault tolerance. { true } Retry_Body { Inv and Pre } • Failure • Clean-up the environment (restore the invariant), terminate the call and report failure to the caller. { true } Rescue_Body { Inv } L10DC
Developer Exceptions • Exceptions are propagated up the call chain (dynamic). • A supplier code can define an exception and raise it, to enable context-sensitive handling of the exception by the various clients. • In Java, an exception is a typed packet of information (object), which is useful in locating and diagnosing faults. Checked exceptions contribute to robustness by forcing the client to process exception explicitly, or propagate it explicitly. L10DC