Presentation is loading. Please wait.

Presentation is loading. Please wait.

Adding Contracts to Ada Ehud Lamm Adding Design By Contract to Ada.

Similar presentations


Presentation on theme: "Adding Contracts to Ada Ehud Lamm Adding Design By Contract to Ada."— Presentation transcript:

1 Adding Contracts to Ada Ehud Lamm Adding Design By Contract to Ada

2 19.7.2002Ada-Europe’2002 1 ADT + Contracts type Stack is tagged private; procedure Init(S:out Stack); procedure Push(S:in out Stack; I:in Integer) at exit Size(S)=old Size(S)+1; procedure Pop(S:in out Stack;I:out Integer) use when not(Is_Empty(S)) at exit Size(S)=old Size(S)-1; function Size(S:Stack) return Natural; function Is_Empty(S:Stack) return Boolean; function Top(S:Stack) return Integer use when not(Is_Empty(S)); Overflow: exception; 1.Contracts are checked at runtime (detection). 2.Contract violations raise exceptions. 3.When possible use the type system instead (e.g., Size) 4.Contracts allow expressing arbitrary boollean assertions.

3 19.7.2002Ada-Europe’2002 2 Design By Contract Annotate each routine with axioms. Pre-Condition & Post-Condition (we will not talk about class invariants) The classic ADT approach (Liskov, Guttag, Meyer)

4 19.7.2002Ada-Europe’2002 3 Design By Contract A contract carries mutual obligations and benefits. The client should only call a routine when the routine’s pre-condition is respected. The routine ensures that after completion its post-condition is respected.

5 19.7.2002Ada-Europe’2002 4 A little polymorphic programming procedure Print_And_Empty(S: in out Stack’class) is i:Integer; begin while not(Is_Empty(S)) loop pop(S,i); put(I); end loop; end; Interface oriented programming Exercise: Prove termination for all possible stacks S.

6 19.7.2002Ada-Europe’2002 5 Oops… type Crazy_Stack is new Stack with null record; procedure Pop(S:in out Crazy_Stack;I:out Integer) use when not(Is_Empty(Stack)) at exit (old Top(S)/=9 and then Size(S)=old Size(S)-1) or (Size(S)=old Size(S)); Does Print_And_Empty work correctly on Crazy_Stacks?

7 19.7.2002Ada-Europe’2002 6 Liskov Substitution Principle LSP Liskov, Wing (TOPLAS, Nov. 1994) Liskov (SIGPLAN, May 1988) Otherwise bad use of public inheritance!

8 19.7.2002Ada-Europe’2002 7 Why is this important? The foundation for subtype polymorphism Bugs surface during maintenance Who is responsible?

9 19.7.2002Ada-Europe’2002 8 Assigning Blame Crucial for managing software production Possible candidates: –The original contractor (Stack) –The polymorphic routine (Print_And_Empty) –The subcontractor (Crazy_Stack) –The user of the pm routine (should know better than to call P&E on Crazy_Stack)

10 19.7.2002Ada-Europe’2002 9 DbC & Inheritance Remember the LSP! “The subclass must require less and ensure more” )Meyer, OOSC) The only question is how to ensure this property!

11 19.7.2002Ada-Europe’2002 10 DbC & LSP – more formal Assume B is derived from A, then for each method P pre(P A ) → pre(P B ) and post(P B ) → post(P A ) A B A B

12 19.7.2002Ada-Europe’2002 11 The Eiffel Approach The programmer is not allowed to make an LSP error… require else ensure then A subclass can only use “or” in pre-cond / “and” in post-cond Other tools are even worse

13 19.7.2002Ada-Europe’2002 12 Wrong Approach “Ensuring” correct hierarchies procedure p(T:A;I:Integer) use when i>0; procedure p(T:B;I:Integer) use when i>10; -- synthesized contract (i>0)V(i>10) Hierarchy is malformed, language hides error.

14 19.7.2002Ada-Europe’2002 13 Solution Interface implied contract can be deduced from code. Hierarchy checking is done according to run time tag of object. (Recall P&E) (more details in the paper and references)

15 19.7.2002Ada-Europe’2002 14 Contract Checking - Analysis procedure Print_And_Empty(S: in out Stack’class) is i:Integer; begin while not(Is_Empty(S)) loop pop(S,i); put(I); end loop; end; P&E is responsible for Stack’s Pop pre-condition. (Stack’s pre implies actual’s pre) Actual’s Pop post-condition must be satisfied when Pop exits Actual Pop’s post condition must imply Stack Pop post-condition

16 19.7.2002Ada-Europe’2002 15 Another example: generics generic with function Sqrt(X:Float) return Float use when X>=0; procedure Print_Quad_Solutions(A,B,C:Float); -- use when B**2-4.0*A*C>=0; If actual Sqrt requires X>0, who is to be blamed when P_Q_S fails?

17 19.7.2002Ada-Europe’2002 16 How can the language help? Run-time enforcement Should allow the programmer to document contracts; in a formal, standard notation Enforce correct contract relations when possible (Hard!) Identify faulty components and assign blame, when violations occur When you cannot use built-in contracts: types (Think of trying to break a contract stating that the Stack contains only positive numbers)

18 19.7.2002Ada-Europe’2002 17 Does Ada need DbC? Ada, The Software Engineering Language Good type system; support for generic programming Ada interface definitions are lacking (e.g., which exceptions are raised by which routine?) Readability and Self-Documenting code Debugging aid Everyone else has it (Eiffel, Java: iContract, jContractor, HandShake, JVMAssert) … BUT: This is a major change

19 19.7.2002Ada-Europe’2002 18 Conclusion Perhaps still too cutting edge?! Is there market demand? Should we do it anyway? Even a rudimentary implementation has important advantages. Simpler than extending the type system The future lies in sw components) COTS )

20 19.7.2002Ada-Europe’2002 19 Ada needs DbC Any Questions?

21 19.7.2002Ada-Europe’2002 20 Implementation Can be implemented using wrapper routines The exact wrapper routine invoked for each call is determined by relevant interface.

22 19.7.2002Ada-Europe’2002 21 Interoperability with the old language Old language calling new, not really an issue (but upstream contractual exceptions may be raised) New language calling old, not really an issue (but compiler should know that a package was compiled with no contracts)


Download ppt "Adding Contracts to Ada Ehud Lamm Adding Design By Contract to Ada."

Similar presentations


Ads by Google