Contract-Based Programming with/without Ada 2012

Slides:



Advertisements
Similar presentations
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
Advertisements

Design by Contract.
Semantics Static semantics Dynamic semantics attribute grammars
Programming Languages and Paradigms
Abstract Data Types Data abstraction, or abstract data types, is a programming methodology where one defines not only the data structure to be used, but.
Software Engineering and Design Principles Chapter 1.
ISBN Chapter 11 Abstract Data Types and Encapsulation Concepts.
1 Specifying Object Interfaces. 2 Major tasks in this stage: --are there any missing attributes or operations? --how can we reduce coupling, make interface.
Software Testing and Quality Assurance
Static and Dynamic Contract Verifiers For Java Hongming Liu.
Lecture 9 Concepts of Programming Languages
Eiffel Language and Design by Contract Contract –An agreement between the client and the supplier Characteristics –Expects some benefits and is prepared.
Adding Contracts to Ada Ehud Lamm Adding Design By Contract to Ada.
Abstract Data Types and Encapsulation Concepts
Computer Science 340 Software Design & Testing Design By Contract.
Ranga Rodrigo. Class is central to object oriented programming.
PZ11A Programming Language design and Implementation -4th Edition Copyright©Prentice Hall, PZ11A - Exception handling Programming Language Design.
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Chapter 25 Formal Methods Formal methods Specify program using math Develop program using math Prove program matches specification using.
Low-Level Detailed Design SAD (Soft Arch Design) Mid-level Detailed Design Low-Level Detailed Design Design Finalization Design Document.
A Survey on Java Modeling Languages Gergely Kovásznai,Eszterházy Károly College Wolfgang Schreiner,Johannes Kepler University Gábor Kusper,Eszterházy Károly.
ISBN Chapter 11 Abstract Data Types and Encapsulation Concepts.
Chapter 3 Part II Describing Syntax and Semantics.
Chapter 10, Slide 1 ABSTRACT DATA TYPES Based on the fundamental concept of ABSTRACTION:  process abstraction  data abstraction Both provide:  information.
ISBN Chapter 11 Abstract Data Types and Encapsulation Concepts.
ADT data abstraction. Abstraction  representation of concepts by their relevant features only  programming has two major categories of abstraction process.
Class Design I Class Contracts Readings: 2 nd Ed: Section 9.5, Advanced Topic nd Ed: Section 8.5, Advanced Topic 8.2 Some ideas come from: “Practical.
ANU COMP2110 Software Design in 2003 Lecture 10Slide 1 COMP2110 Software Design in 2004 Lecture 12 Documenting Detailed Design How to write down detailed.
L13: Design by Contract Definition Reliability Correctness Pre- and post-condition Asserts and Exceptions Weak & Strong Conditions Class invariants Conditions.
SWE 4743 Abstract Data Types Richard Gesick. SWE Abstract Data Types Object-oriented design is based on the theory of abstract data types Domain.
1 CS Programming Languages Class 22 November 14, 2000.
1 Copyright © 1998 by Addison Wesley Longman, Inc. Chapter 10 Abstraction - The concept of abstraction is fundamental in programming - Nearly all programming.
1 Assertions. 2 A boolean expression or predicate that evaluates to true or false in every state In a program they express constraints on the state that.
PROGRAMMING PRE- AND POSTCONDITIONS, INVARIANTS AND METHOD CONTRACTS B MODULE 2: SOFTWARE SYSTEMS 13 NOVEMBER 2013.
DBC NOTES. Design By Contract l A contract carries mutual obligations and benefits. l The client should only call a routine when the routine’s pre-condition.
Object Design More Design Patterns Object Constraint Language Object Design Specifying Interfaces Review Exam 2 CEN 4010 Class 18 – 11/03.
Design by Contract. The Goal Ensure the correctness of our software (correctness) Recover when it is not correct anyway (robustness) Correctness: Assertions.
1 Exception handling Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section 11.1.
ISBN Chapter 12 Support for Object-Oriented Programming.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Chapter 11: Abstract Data Types Lecture # 17. Chapter 11 Topics The Concept of Abstraction Advantages of Abstract Data Types Design Issues for Abstract.
J-P. Rosen Adalog J-P. Rosen Adalog The contract model of Ada 2012.
SWEN421 – Lecture 3 Building High Integrity Software with SPARK Ada
PZ11A Programming Language design and Implementation -4th Edition
Chapter 6 CS 3370 – C++ Functions.
Design by Contract Jim Fawcett CSE784 – Software Studio
Design by Contract Jim Fawcett CSE784 – Software Studio
Abstract Data Types and Encapsulation Concepts
Type Checking Generalizes the concept of operands and operators to include subprograms and assignments Type checking is the activity of ensuring that the.
ABSTRACT DATA TYPES Based on the fundamental concept of ABSTRACTION:
11.1 The Concept of Abstraction
Lecture 9 Concepts of Programming Languages
Specifying Object Interfaces
Abstract Data Types and Encapsulation Concepts
Java Programming Language
Abstract Data Types and Encapsulation Concepts
Final Review In Text: Chapters 1-3, 5-12,
Exception handling Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section 11.1.
Java Modeling Language (JML)
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
Midterm Review In Text: Chapters 1-3, 5-11, 15.
Computer Science 340 Software Design & Testing
Exception handling Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section 11.1.
Exception handling Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section 11.1.
Exception handling Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section 11.1.
11.1 The Concept of Abstraction
Lecture 9 Concepts of Programming Languages
Chapter 11 Abstraction - The concept of abstraction is fundamental in
Presentation transcript:

Contract-Based Programming with/without Ada 2012 Patrick Rogers 9 May 2019

Contract-Based Programming The idea of source code having roles of “client” and “supplier” under a binding “contract” Example: suppliers provide subprograms, clients call them “Contracts” Specifications that govern the interaction of software elements with their clients (Bertrand Meyer) “Binding contracts” require enforcement At run-time via exceptions At compile-time in some cases During static analysis prior to compilation Meyer, A Touch of Class, pg 68 and https://archive.eiffel.com/doc/manuals/technology/contract/

Terminology Assertion: a boolean expression expected to be True Said “to hold” when True Precondition: an assertion expected to hold prior to a call to a given subprogram Postcondition: an assertion expected to hold after a given subprogram call returns Invariant: an assertion expected to hold for all objects of a given abstract data type when viewed as a client (i.e., from outside the defining package) Other important forms of contract as well Type predicates, global object access (Ada 202x), etc. RM 11.4.2

Contracts In Ada 2012 Pre- and postconditions specify obligations Type invariants ensure properties of ADT objects over their lifetimes procedure Push (This : in out Stack; Value : Element) with Pre => not Full (This), Post => not Empty (This) and Top_Element (This) = Value; … function Top_Element (This : Stack) return Element with Pre => not Empty (This); function Full (This : Stack) return Boolean; Caller’s Arbitrary user-defined Boolean expressions Implementer’s Any object of the type type Airlock is limited private with Type_Invariant => not Both_Hatches_Open (Airlock); Arbitrary user-defined Boolean expression

Pre/Postcondition Semantics If defined, evaluated automatically at run-time Each raises an exception if evaluates to False If defined Pre False Raise Assertion_Error exception Subprogram Call Post False If defined

Initial (Incomplete) Pre & Post Example generic type Element is private; package Bounded_Stacks is type Stack (Capacity : Positive) is private; procedure Push (This : in out Stack; Value : Element) with Pre => not Full (This), Post => not Empty (This) and Top_Element (This) = Value; procedure Pop (This : in out Stack; Value : out Element) with Pre => not Empty (This), Post => not Full (This); function Top_Element (This : Stack) return Element with Pre => not Empty (This); function Empty (This : Stack) return Boolean; function Full (This : Stack) return Boolean; … end Bounded_Stacks;

Pre & Post Example Body package body Bounded_Stacks is procedure Reset (This : in out Stack) is begin This.Top := 0; end Reset; procedure Push (This : in out Stack; Item : Element) is This.Top := This.Top + 1; This.Values (This.Top) := Item; end Push; procedure Pop (This : in out Stack; Item : out Element) is Item := This.Values (This.Top); This.Top := This.Top - 1; end Pop; … end Bounded_Stacks;

Referencing Prior Values In Post Values as they were just before the call Uses language-defined attribute object'Old Can be applied to most any non-limited object visible procedure Push (This : in out Stack; Item : Element) with Pre => not Full (This), Post => not Empty (This) and Top_Element (This) = Item and Extent (This) = Extent (This'Old) + 1 and Unchanged (This'Old, Within => This); function Extent (This : Stack) return Element_Count; function Unchanged (Invariant_Part, Within : Stack) return Boolean; … Value before call Value after call

Referencing Function Result In Post I.e., the value returned by a call to the associated function Via attribute function-name'Result Only for functions, only in postconditions function Empty (This : Stack) return Boolean with Post => Empty'Result = (Extent (This) = 0), Result of call function Total (This : Transactions_List) return Currency with Pre => All_Positive (This), Post => (if Length (This) = 0 then Total'Result = 0.0 else Total'Result >= 0.0);

Advantages Over Explicit Checks Pre/postconditions can be turned off Like language-defined checks Explicit checks cannot be disabled except by changing the source code Conditional compilation via preprocessor (“ifdef”) Conditional compilation via static Boolean constants … procedure Push (This : in out Stack; Value : Element) is begin if Debugging then if Full (This) then raise Overflow; end if; end Push; see OOSC pg 343, 345… … Debugging : constant Boolean := True;

Not Using Ada 2012? Not A Problem! Use pragma form of Pre, Post, and Type_Invariant GNAT defines the pragmas GNAT back-ports attributes ‘Old and ‘Result You won’t have some of the convenient syntax Quantified Expressions Expression Functions Conditional Expressions Hence you’ll write more function bodies than in Ada 2012 Note the Containers packages came in Ada 2005

Pre/Post Example in Ada 95 and 2005 generic type Element is private; -- The type of values contained by objects of type Stack package Bounded_Stacks_95 is type Stack (Capacity : Physical_Capacity) is private; procedure Push (This : in out Stack; Item : Element); pragma Pre (not Full (This)); pragma Post ( not Empty (This) and Top_Element (This) = Item and Extent (This) = Extent (This'Old) + 1 and Unchanged (This'Old, Within => This)); procedure Pop (This : in out Stack; Item : out Element); pragma Pre (not Empty (This)); pragma Post ( not Full (This) and Item = Top_Element (This'Old) and Extent (This) = Extent (This'Old) - 1 and Unchanged (This, Within => This'Old)); function Top_Element (This : Stack) return Element; function Empty (This : Stack) return Boolean; pragma Post (Empty'Result = (Extent (This) = 0)); …

Type Invariants

Type Invariants Represent conditions that must hold over the lifetime of objects Pre/postconditions apply only to subprograms Other operations change state too Assignment Others… Invariants apply across such operations Therefore additional points where checked

Part of Abstract Data Type (ADT) Concept Hence only allowed for private types Bertrand Meyer calls these “Class Invariants” Checked operations are those available to clients Those define the ADT interface The “primitive operations” for a type Internal operations are not checked Part of the implementation Not visible to client code See OOSC pg 363 for discussion of this topic (“Class Invariants”) Invariant for Bank Account ADT Consistent Balance: Total Deposits - Total Withdrawals = Balance

Bank Account ADT with Type Invariant Consistent Balance: Total Deposits - Total Withdrawals = Balance package Bank is type Account is private with Type_Invariant => Consistent_Balance (Account); type Currency is delta 0.01 digits 12; … function Consistent_Balance (This : Account) return Boolean; private end Bank; Any object of type Account The lists are used for tracking and reporting. Called automatically for all Account objects

Type Invariant Verifications Automatically inserted by compiler Evaluated as a postcondition of any operation that creates, evaluates or returns a value of the type When objects first created Assignment by clients Type conversions since that creates new instances Not evaluated on internal state changes Internal routine calls Internal assignments Remember these are abstract data types These subprograms include both the primitive ops as well as those that have a mode out param or function result of a composite type containing the type in question, as long as the op is declared in the same scope as the type in question. So a level of indirection is included for these types as well.

Example Type Invariant Realization (Spec) … package Bank is type Account is private with Type_Invariant => Consistent_Balance (Account); type Currency is delta 0.01 digits 12; function Consistent_Balance (This : Account) return Boolean; private package Transactions is new Ada.Containers.Doubly_Linked_Lists (Element_Type => Currency); type Account is record Owner : Unbounded_String; Current_Balance : Currency := 0.0; Withdrawals : Transactions.List; -- initially empty Deposits : Transactions.List; -- initially empty end record; function Total (This : Transactions.List) return Currency; end Bank;

Example Type Invariant Realization (Body) … package body Bank is function Total (This : Transactions.List) return Currency is Result : Currency := 0.0; begin for Value of This loop Result := Result + Value; end loop; return Result; end Total; function Consistent_Balance (This : Account) return Boolean is (Total (This.Deposits) - Total (This.Withdrawals) = This.Current_Balance); end Bank; No iteration if list is empty

Invariants Are Not Foolproof Access to ADT representation via pointer allows back door manipulation These are private types, so access to internals must be granted by the private type’s code Granting internal representation access for an ADT is a highly questionable design!

Type Invariant in Ada 95/2005 package Bank_95 is type Account is private; pragma Type_Invariant (Account, Consistent_Balance (Account)); function Consistent_Balance (This : Account) return Boolean; type Currency is delta 0.01 digits 12; procedure Deposit (This : in out Account; Amount : Currency); pragma Pre (Open (This) and Amount > 0.0); pragma Post (Balance (This) = Balance (This)'Old + Amount); … private … as before, but note Containers packages are as of Ada 2005 end Bank_95;

Closing Remarks

Contract-Based Programming Benefits Facilitates building software with reliability built-in Software cannot work well unless “well” is carefully defined Clarifies the design by defining obligations Enhances readability and understandability Specification contains explicitly expressed properties of code Aids in development and debugging Facilitates unit testing Postconditions express the unit tests’ conditions Facilitates tool-based analysis CodePeer can use the pragmas even if your (non-GNAT) compiler ignores them

Things Not Shown Class-wide forms Inherited by derived types Pre_Class Post_Class Type_Invariant_Class Pragma for (static and dynamic) predicates Pragma for Default_Initial_Condition Et cetera See the GNAT Reference Manual for details “Implementation Defined Pragmas” section

https://learn.adacore.com

Questions?