1 Design by Contract Software Engineering

Design by Contract

Every software element is intended to satisfy a certain goal, for the benefit of other software elements (and ultimately of human users).

This goal is the element’s contract.

The contract of any software element should be ¾ Explicit. ¾ Part of the software element itself.

2 Design by Contract Software Engineering

Design by Contract: applications

¾ Built-in correctness ¾ Automatic documentation ¾ Self-debugging, self-testing code ¾ Get inheritance right ¾ Get exceptions right ¾ Give managers better control tools

3 Design by Contract Software Engineering

1 Software construction: the underlying view

Constructing systems as structured collections of cooperating software elements — suppliers and clients — cooperating on the basis of clear definitions of obligations and benefits

These definitions are the contracts

4 Design by Contract Software Engineering

Properties of contracts

A contract: ¾ Binds two parties (or more): supplier, client ¾ Is explicit (written) ¾ Specifies mutual obligations and benefits ¾ Usually maps obligation for one of the parties into benefit for the other, and conversely ¾ Has no hidden clauses: obligations are those specified ¾ Often relies, implicitly or explicitly, on general rules applicable to all contracts (laws, regulations, standard practices)

5 Design by Contract Software Engineering

A human contract

deliver OBLIGATIONS BENEFITS (Satisfy :) (From postcondition:) Client Bring package before Get package delivered 4 p.m.; pay fee. by 10 a.m. next day.

(Satisfy postcondition:) (From precondition:) Supplier Deliver package by Not required to do 10 a.m. next day. anything if package delivered after 4 p.m., or fee not paid.

6 Design by Contract Software Engineering

2 EiffelStudio documentation

Produced automatically from class text Available in text, HTML, Postscript, RTF, FrameMaker and many other formats Numerous views, textual and graphical

7 Design by Contract Software Engineering

Contracts for documentation

Demo

LINKED_LIST Documentation, generated by EiffelStudio

8 Design by Contract Software Engineering

Contract form: Definition

Simplified form of class text, retaining interface elements only: ¾ Remove any non-exported (private) feature.

For the exported (public) features: ¾ Remove body (do clause). ¾ Keep header comment if present. ¾ Keep contracts: , postconditions, . ¾ Remove any contract clause that refers to a secret feature. (What’s the problem?)

9 Design by Contract Software Engineering

3 The different forms of a class

All features and contract Only the exported (non secret) clauses elements

Elements from the class only Text view: Contract view: text form short form

Elements from the class and Flat view: Interface view: it’s ancestors flat form flat short form

10 Design by Contract Software Engineering

Export rule for preconditions

In feature {A, B, C} r (…) is require some_property

some_property must be exported (at least) to A, B and C! No such requirement for postconditions and invariants.

11 Design by Contract Software Engineering

Contracts for analysis, specification deferred class VAT inherit TANK feature in_valve, out_valve: VALVE fill is -- Fill the vat. require in_valve.open out_valve.closed deferred ensure in_valve.closed out_valve.closed is_full end empty, is_full, is_empty, gauge, maximum, ... [Other features] ... invariant is_full = (gauge >= 0.97 ∗ maximum) and (gauge <= 1.03 ∗ maximum) end Chair of Software Engineering

4 Contracts for testing and debugging

¾ Contracts express implicit assumptions behind code ¾ A bug is a discrepancy between intent and code ¾ Contracts state the intent!

In EiffelStudio: select compilation option for run-time contract monitoring at level of: ¾ Class ¾ Cluster ¾ System

May disable monitoring when releasing software A revolutionary form of quality assurance

13 Design by Contract Software Engineering

Lists in EiffelBase

before after item “Iowa" 1 count Cursor back forth

start finish

index

14 Design by Contract Software Engineering

Trying to insert too far right

after

"Iowa" 1 count

Cursor (Already past last element!)

15 Design by Contract Software Engineering

5 A command and its contract

Precondition

Postcondition

16 Design by Contract Software Engineering

Moving the cursor forward

before after

"Iowa" 1 count Cursor forth

index

17 Design by Contract Software Engineering

Two queries, and command “forth″

18 Design by Contract Software Engineering

6 Where the cursor may go

before after item

0 1 count count+1

Valid cursor positions

19 Design by Contract Software Engineering

From the invariant of class LIST

Valid cursor positions

20 Design by Contract Software Engineering

Contract monitoring

A contract violation always signals a bug:

¾ Precondition violation: bug in client

¾ Postcondition violation: bug in routine

21 Design by Contract Software Engineering

7 Contracts and inheritance

Issues: what happens, under inheritance, to

¾ Class invariants?

¾ Routine preconditions and postconditions?

22 Design by Contract Software Engineering

Invariants

Invariant Inheritance rule: ¾ The invariant of a class automatically includes the invariant clauses from all its parents, “and”-ed. Accumulated result visible in flat and interface forms.

23 Design by Contract Software Engineering

Contracts and inheritance

A r is C require a1: A … α a1.r (…) ensure β Correct call in C: if a1.α then r ++ a1.r (...) D B r is -- Here a1.β hold require end γ ensure

Client ++ Redefinition Inheritance δ

24 Design by Contract Software Engineering

8 Assertion redeclaration rule

When redeclaring a routine, we may only:

¾ Keep or weaken the precondition

¾ Keep or strengthen the postcondition

25 Design by Contract Software Engineering

Assertion redeclaration rule in Eiffel

A simple language rule does the trick!

Redefined version may have nothing (assertions kept by default), or

require else new_pre ensure then new_post

Resulting assertions are: ¾ original_precondition or new_pre

¾ original_postcondition and new_post

26 Design by Contract Software Engineering

Contracts as a management tool

High-level view of modules for the manager:

¾ Follow what’s going on without reading the code

¾ Enforce strict rules of cooperation between units of the system

¾ Control outsourcing

27 Design by Contract Software Engineering

9 Checking input: filter modules

Contracts are not input checking tests...... but they can help weed out undesirable input

External Input & objects validation Processing modules modules

Postconditions ⇒ Preconditions No preconditions! here only

28 Design by Contract Software Engineering

Precondition design

The client must guarantee the precondition before the call. This does not necessarily mean testing for the precondition.

Scheme 1 (testing):

if not my_stack.is_full then my_stack.put (some_element) end

Scheme 2 (guaranteeing without testing):

my_stack.remove ... my_stack.put (some_element)

29 Design by Contract Software Engineering

Another example sqrt (x, epsilon: REAL): REAL is -- Square root of x, precision epsilon require

x >= 0 epsilon >= 0 do ... ensure abs (Result ^ 2 – x) <= 2 * epsilon * Result

end

30 Design by Contract Software Engineering

10 The contract

sqrt OBLIGATIONS BENEFITS (Satisfy precondition:) (From postcondition:) Client Provide non-negative Get square root within value and precision requested precision. that is not too small. (Satisfy postcondition:) (From precondition:) Supplier Produce square root Simpler processing within requested thanks to assumptions precision. on value and precision.

31 Design by Contract Software Engineering

Not defensive programming

It is not acceptable to have a routine of the form

sqrt (x, epsilon: REAL): REAL is -- Square root of x, precision epsilon require x >= 0 epsilon >= 0 do if x < 0 then … Do something about it (?) … else … normal square root computation … end ensure abs (Result ^ 2 – x) <= 2 * epsilon * Result end

32 Design by Contract Software Engineering

Not defensive programming

For every consistency condition that is required to perform a certain operation: ¾ Assign responsibility for the condition to one of the contract’s two parties (supplier, client). ¾ Stick to this decision: do not duplicate responsibility.

Simplifies software and improves global reliability.

33 Design by Contract Software Engineering

11 Interpreters

class BYTECODE_PROGRAM feature

verified: BOOLEAN

trustful_execute (program: BYTECODE) is require ok: verified do ... end distrustful_execute (program: BYTECODE) is do verify if verified then trustful_execute (program) end end verify is do ... end

end

34 Design by Contract Software Engineering

How strong should a precondition be?

Two opposite styles: ¾ Tolerant: weak preconditions (including the weakest, True: no precondition). ¾ Demanding: strong preconditions, requiring the client to make sure all logically necessary conditions are satisfied before each call.

Partly a matter of taste.

But: demanding style leads to a better distribution of roles, provided the precondition is:

¾ Justifiable in terms of the specification only. ¾ Documented (through the short form). ¾ Reasonable!

35 Design by Contract Software Engineering

A demanding style

sqrt (x, epsilon: REAL): REAL is -- Square root of x, precision epsilon -- Same version as before require x >= 0 epsilon >= 0 do ... ensure abs (Result ^ 2 – x) <= 2 * epsilon * Result end

36 Design by Contract Software Engineering

12 A tolerant style sqrt (x, epsilon: REAL): REAL is NO INPUT -- Square root of x, precision epsilon TOO BIG OR require TOO SMALL! True do if x < 0 then … Do something about it (?) … else … normal square root computation … computed := True end ensure computed implies abs (Result ^ 2 – x) <= 2 * epsilon * Result end

37 Design by Contract Software Engineering

Contrasting styles put (x: G) is -- Push x on top of stack. require not is_full do .... end tolerant_put (x: G) is -- Push x if possible, otherwise set impossible to -- True. do if not is_full then put (x) else impossible := True end end

38 Design by Contract Software Engineering

Invariants and business rules

Invariants are absolute consistency conditions. They can serve to represent business rules if knowledge is to be built into the software. Form 1

invariant not_under_minimum: balance >= Minimum_balance

Form 2

invariant not_under_minimum_if_normal: normal_state implies (balance >= Minimum_balance)

39 Design by Contract Software Engineering

13 Power of the assertion language

Assertion language:

¾ Not first-order predicate calculus

¾ But powerful through: Function calls

¾ Even allows to express: Loop properties

40 Design by Contract Software Engineering

Loop trouble

Loops can be hard to get right:

¾ “Off-by-one” ¾ Infinite loops ¾ Improper handling of borderline cases

For example: binary search feature

41 Design by Contract Software Engineering

The answer: loop contracts

Use of loop variants and invariants.

A loop is a way to compute a certain result by successive approximations.

(e.g. computing the maximum value of an array of integers)

42 Design by Contract Software Engineering

14 Computing the max of an array highest (sl: LIST [STRING]): STRING is -- Greatest element of sl require sl /= Void not sl.is_empty do from sl.start ; Result := "" until sl.after loop Result := greater (Result, sl.item)

sl.forth end end

43 Design by Contract Software Engineering

Loop as approximation strategy

s1 s2 si sn

Result = s1

Result = Max (s1, s2)

Result = Max (s1, s2, ..., si)

Result = Max (s1, s2, ..., si , ..., sn)

44 Design by Contract Software Engineering

The loop invariant from sl.start ; Result := "“ invariant sl.index >= 1 sl.index <= sl.count + 1 -- Result is greatest of elements so far until sl.after loop Result := greater (Result, sl.item)

sl.forth end

45 Design by Contract Software Engineering

15 Loop invariant

(Do not confuse with class invariant)

Property that is:

¾ Satisfied after initialization (from clause)

¾ Preserved by every loop iteration (loop clause) when executed with the exit condition (until clause) not satisfied

46 Design by Contract Software Engineering

The loop invariant from sl.start ; Result := "" invariant sl.index >= 1 sl.index <= sl.count + 1 -- Result is greatest of elements so far until sl.after loop Result := greater (Result, sl.item)

sl.forth end

47 Design by Contract Software Engineering

The loop invariant (better) from sl.start ; Result := "" invariant sl.index >= 1 sl.index <= sl.count + 1 -- If there are any previous elements, Result is the greatest until sl.after loop Result := greater (Result, sl.item)

sl.forth end

48 Design by Contract Software Engineering

16 The effect of the loop

Invariant satisfied after from initialization sl.start ; Result := "" invariant sl.index >= 1 sl.index <= sl.count + 1 -- Result is greatest of elements so far until Exit condition sl.after satisfied at end loop At end: invariant and exit condition Result := greater (Result, sl.item) • All elements visited (sl.after )

sl.forth • Result is highest of their names end Invariant satisfied after each iteration

49 Design by Contract Software Engineering

Loop semantics rule

The effect of a loop is the combination of:

¾ Its invariant

¾ Its exit condition

50 Design by Contract Software Engineering

How do we know the loop terminates?

from sl.start ; Result := "“ invariant sl.index >= 1 sl.index <= sl.count + 1 -- If there are any previous elements, Result is the greatest until sl.after loop Result := greater (Result, sl.item)

sl.forth end

51 Design by Contract Software Engineering

17 Loop variant

Integer expression that must:

¾Be non-negative when after initialization (from)

¾Decrease (i.e. by at least one), while remaining non- negative, for every iteration of the body (loop) executed with exit condition not satisfied

52 Design by Contract Software Engineering

The variant for our loop from sl.start ; Result := "“ variant sl.count − sl.index + 1 invariant sl.index >= 1 sl.index <= sl.count + 1 -- If there are any previous elements, Result is the greatest until sl.after loop Result := greater (Result, sl.item)

sl.forth end

53 Design by Contract Software Engineering

Another contract construct

Check instruction: ensure that a property is True at a certain point of the routine execution.

E.g. Tolerant style example: Adding a check clause for readability.

54 Design by Contract Software Engineering

18 Precondition design

Scheme 2 (guaranteeing without testing): my_stack.remove check my_stack_not_full: not my_stack.is_full end my_stack.put (some_element)

55 Design by Contract Software Engineering

19