1 / 22

Adding Contracts to Ada

Adding Contracts to Ada. Adding Design By Contract to Ada. Ehud Lamm. 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)

gitano
Download Presentation

Adding Contracts to Ada

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. Adding Contracts to Ada Adding Design By Contract to Ada Ehud Lamm

  2. 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; • Contracts are checked at runtime (detection). • Contract violations raise exceptions. • When possible use the type system instead (e.g., Size) • Contracts allow expressing arbitrary boollean assertions. Ada-Europe’2002

  3. 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) Ada-Europe’2002

  4. 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. Ada-Europe’2002

  5. Interface oriented programming 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; Exercise: Prove termination for all possible stacks S. Ada-Europe’2002

  6. 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? Ada-Europe’2002

  7. IS-A Otherwise bad use of public inheritance! Liskov Substitution PrincipleLSP Liskov (SIGPLAN, May 1988) Liskov, Wing (TOPLAS, Nov. 1994) Ada-Europe’2002

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

  9. 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) Ada-Europe’2002

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

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

  12. 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 Ada-Europe’2002

  13. 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. Ada-Europe’2002

  14. 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) Ada-Europe’2002

  15. 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 postcondition must imply Stack Pop post-condition 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; Ada-Europe’2002

  16. 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? Ada-Europe’2002

  17. 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) Ada-Europe’2002

  18. 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 Ada-Europe’2002

  19. 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) Ada-Europe’2002

  20. Ada needs DbC Any Questions? Ada-Europe’2002

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

  22. 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) Ada-Europe’2002

More Related