Copyright W. Howden1 Programming by Contract CSE 111 6/4/2014.

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

Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Design by Contract.
PZ03D Programming Language design and Implementation -4th Edition Copyright©Prentice Hall, PZ03D - Program verification Programming Language Design.
Automatic Verification Book: Chapter 6. What is verification? Traditionally, verification means proof of correctness automatic: model checking deductive:
Reasoning About Code; Hoare Logic, continued
Copyright © 2006 Addison-Wesley. All rights reserved.1-1 ICS 410: Programming Languages Chapter 3 : Describing Syntax and Semantics Axiomatic Semantics.
ISBN Chapter 3 Describing Syntax and Semantics.
Copyright © 2006 Addison-Wesley. All rights reserved. 3.5 Dynamic Semantics Meanings of expressions, statements, and program units Static semantics – type.
1 Design by Contract Building Reliable Software. 2 Software Correctness Correctness is a relative notion  A program is correct with respect to its specification.
Program Proving Notes Ellen L. Walker.
1 Semantic Description of Programming languages. 2 Static versus Dynamic Semantics n Static Semantics represents legal forms of programs that cannot be.
CS 355 – Programming Languages
Copyright W. Howden1 Lecture 13: Programming by Contract.
Software Testing and Quality Assurance
Static and Dynamic Contract Verifiers For Java Hongming Liu.
OOP #10: Correctness Fritz Henglein. Wrap-up: Types A type is a collection of objects with common behavior (operations and properties). (Abstract) types.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
CS 330 Programming Languages 09 / 16 / 2008 Instructor: Michael Eckmann.
Describing Syntax and Semantics
MCA –Software Engineering Kantipur City College. Topics include  Formal Methods Concept  Formal Specification Language Test plan creation Test-case.
©Ian Sommerville 2004Software Engineering, 7th edition. Chapter 10 Slide 1 Formal Specification.
Ranga Rodrigo. Class is central to object oriented programming.
1 Abstraction  Identify important aspects and ignore the details  Permeates software development programming languages are abstractions built on hardware.
1 Program Correctness CIS 375 Bruce R. Maxim UM-Dearborn.
WXGE6103 Software Engineering Process and Practice Formal Specification.
ISBN Chapter 3 Describing Semantics -Attribute Grammars -Dynamic Semantics.
CS 261 – Data Structures Preconditions, Postconditions & Assert.
CS 363 Comparative Programming Languages Semantics.
Mr. Dave Clausen1 La Cañada High School Chapter 6: Repetition Statements.
Introduction to Problem Solving. Steps in Programming A Very Simplified Picture –Problem Definition & Analysis – High Level Strategy for a solution –Arriving.
Reading and Writing Mathematical Proofs Spring 2015 Lecture 4: Beyond Basic Induction.
Chapter 5: Sequences, Mathematical Induction, and Recursion 5.5 Application: Correctness of Algorithms 1 [P]rogramming reliability – must be an activity.
Reasoning about programs March CSE 403, Winter 2011, Brun.
ISBN Chapter 3 Describing Semantics.
Chapter 3 Part II Describing Syntax and Semantics.
Semantics In Text: Chapter 3.
Software Reliability. Risks of faulty software  Example: –Therak 25, –AT&T network failure –Airport traffic control  Costs of software errors can be.
COP4020 Programming Languages Introduction to Axiomatic Semantics Prof. Robert van Engelen.
David Streader Computer Science Victoria University of Wellington Copyright: David Streader, Victoria University of Wellington Debugging COMP T1.
13 Aug 2013 Program Verification. Proofs about Programs Why make you study logic? Why make you do proofs? Because we want to prove properties of programs.
ANU COMP2110 Software Design in 2003 Lecture 10Slide 1 COMP2110 Software Design in 2004 Lecture 12 Documenting Detailed Design How to write down detailed.
Defensive Programming CNS 3370 Copyright 2003, Fresh Sources, Inc.
Static Techniques for V&V. Hierarchy of V&V techniques Static Analysis V&V Dynamic Techniques Model Checking Simulation Symbolic Execution Testing Informal.
Dr. Naveed Riaz Design and Analysis of Algorithms 1 1 Formal Methods in Software Engineering Lecture # 26.
Program Correctness. The designer of a distributed system has the responsibility of certifying the correctness of the system before users start using.
CSC3315 (Spring 2009)1 CSC 3315 Languages & Compilers Hamid Harroud School of Science and Engineering, Akhawayn University
C HAPTER 3 Describing Syntax and Semantics. D YNAMIC S EMANTICS Describing syntax is relatively simple There is no single widely acceptable notation or.
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.
Design by Contract. The Goal Ensure the correctness of our software (correctness) Recover when it is not correct anyway (robustness) Correctness: Assertions.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Spring 2017 Program Analysis and Verification
Formal Specification.
SWEN421 – Lecture 3 Building High Integrity Software with SPARK Ada
Chapter 3 of Programming Languages by Ravi Sethi
Chapter 6 CS 3370 – C++ Functions.
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Mathematical Structures for Computer Science Chapter 1
Lecture 5 Floyd-Hoare Style Verification
Programming Languages and Compilers (CS 421)
Programming Languages 2nd edition Tucker and Noonan
Semantics In Text: Chapter 3.
Predicate Transformers
The Zoo of Software Security Techniques
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
Programming Languages and Compilers (CS 421)
Programming Languages 2nd edition Tucker and Noonan
COP4020 Programming Languages
Presentation transcript:

Copyright W. Howden1 Programming by Contract CSE 111 6/4/2014

Contracts Client and Supplier Contract: –if client satisfies certain preconditions, then the supplier will produce a product satisfying certain postconditions Copyright W. Howden26/4/2014

Design by Contract All of the components (classes, methods and procedures) have a stated contract that they will fulfill Benefits –reusable components –correct interfaces when integrating components –predictable results 6/4/2014Copyright W. Howden3

Software Contracts Methods and procedures precondition: required input properties postconditions: guaranteed output properties, provided precondition is satisfied Classes method contracts class invariants –properties that are true on completion of constructor and true before and after each method application 6/4/2014Copyright W. Howden4

Assertions Expected properties of program state (values of variables) Used to specify preconditions, postconditions and class invariants Also used for intermediate assertions –statements about what is expected to be true at intermediate points in a programs execution 6/4/2014Copyright W. Howden5

Assertions and Preconditions Assertion should appear as first line in a method Asserts that whenever execution reaches this location, this property must be true 6/4/2014Copyright W. Howden6

Assertions and Postconditions Executable dynamic testing assertions should appear before each return statement State that the asserted property is true whenever the program returns from that location Static assertions can be put after the return points 6/4/2014Copyright W. Howden7

Assertions and Class Invariants Should appear as postconditions in constructors and all other methods Should appear as preconditions in all methods For public methods, input should be checked directly and not by an assertion –assertions can be turned off after debugging 6/4/2014Copyright W. Howden8

Assertion Languages Static analysis –non-executable informal prose statements or formal statements in a formal logic Dynamic analysis executable expressions that return T or F executed during testing, but turned off during production use Copyright W. Howden96/4/2014

Validating Contracts Static: –prove that if the precondition holds then when the program reaches termination, the postcondition holds Dynamic: –use executable assertions for pre and postconditions. Run tests. If a postcondition does not hold when the precondition holds, the contract is not valid. If a precondition does not hold either a test is faulty or the program and/or precondition need to be corrected Copyright W. Howden106/4/2014

Lecture Topics Static analysis(verification) of method/procedure and class contracts –sometimes called proofs of correctness Dynamic analysis (testing) with Java assertions –pre and postconditions –class invariants, etc. Copyright W. Howden116/4/2014

Why Learn About Proofs? For new complex logic, invaluable check against reasoning flaws Even if never formally done, provides a way of looking at a program that can guide code reading, or informal analysis Are the means of proving properties of standard algorithms (e.g. sorting) Copyright W. Howden126/4/2014

Beams and Girders Proved algorithms and state models are the beams and girders of a software construction project These are the pieces with proved properties that we can rely on Abstract, so must be translated into programming language code Construction involves using these to build a specific application product 6/4/2014Copyright W. Howden13

Informal and Formal Proofs Informal precise state assertions, but not in a formal logical language similar to the language of informal mathematics Formal uses formal semantics for programming language statements very detailed, and hard to construct 6/4/2014Copyright W. Howden14

Copyright W. Howden15 Partial Correctness and Termination Suppose that A 1 is the precondition for a method m and A n is the postcondition. Correctness: m is totally correct if it is partially correct and it always terminates Definition of partial correctness: if A 1 is true at the beginning of an execution and if m is executed and terminates, then A n will be true at the end of the execution 6/4/2014

Copyright W. Howden16 Proof Technique Add intermediate assertions A i to the method. –breaks down proof into easily handled chunks Make sure that each loop has at least one intermediate assertion For each pair of assertions (X,Y) where there is a subpath p from X to Y, which has no other assertions on it, prove its verification condition: if X is true at the beginning of p, and p is executed, then Y will be true at the end of p 6/4/2014

Proof Method Validity? Consider any execution path P P can be broken up into a sequence of subpaths p, which go from one assertion to the next with no assertion in between If all of the verification conditions for the subpaths are true, we can join them together to provide a proof for the whole path 6/4/2014Copyright W. Howden17

Copyright W. Howden18 Verification Example Program multiplies two numbers x and y by adding up y x times Input (precondition) assertion Pre, output (postcondition) assertion Post, intermediate loop invariant assertion IA 6/4/2014

Copyright W. Howden196/4/2014

Copyright W. Howden20 Verification Conditions for Example Prove that 1.if Pre is true then IA will be true 2.if IA is true and Count = 0 then Post will be true 3.If IA is true and Count 0 then IA will be true 6/4/2014

Proof of Verification Condition 3 Suppose that we are at IA and x*y = Product + Count*Y is true. If we go around the loop, Product is incremented by y, and Count is decremented by 1. This means the expression on the right would get larger by y, and then smaller by y, leaving its value the same. So if the relationship was true before the loop, it will also be true after the loop. 6/4/2014Copyright W. Howden21

Termination Proofs If there are no loops in m, and all called methods are terminate, then m must terminate For loops, look for a counter that approaches an upper (lower) limit and is incremented (decremented) on every path through the loop 6/4/2014Copyright W. Howden22

Copyright W. Howden23 Termination Proof for Multiply Example Count initialized to x >=0 Loop terminates if Count == 0 For each iteration Count is decremented by 1 so loop must terminate Note: if Precondition x>=0 is removed from example and input x can be negative, algorithm will not always terminate (i.e. when x < 0), but program is still partially correct 6/4/2014

Termination Bug Example Application: MS Zune MM player Failure: December 31, 2008, device would not boot – infinite loop Faulty procedure –Input = day count relative to origin year Code suppose to figure out current year. –e.g. if days = 500 it must be /4/2014Copyright W. Howden24

Zune Related Code year = ORIGINYEAR; /* = 1980 */ while (days > 365 ) { if isLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { days -= 365; year += 1; } 6/4/2014Copyright W. Howden25

(Attempted) Termination Proof Decremented counter: days Termination condition: days <= 365 When traversing loop, if year is a leap year, and days (remaining) is = 366, then the loop is traversed with no changes to the counter (days) i.e. there is a path through the loop on which the counter is not decremented, 6/4/2014Copyright W. Howden26

Examples from DS isMember() checks to see if DB in-memory vector has an entry with a given name. Our assertions capture what the program is supposed to do deleteMember() is more complex 6/4/2014Copyright W. Howden27

isMember() with Verification Assertions 6/4/2014Copyright W. Howden28 public boolean isMember(String name) { /** Pre: for j = 0 to numberMembers-1 membersData[j].name != null /** numberMembers -1 >=0 for (int i=0; i <= numberMembers-1; ++i) {/** for j = 0 to i-1 membersData[j].name != name /** i <= numberMembers-1 if (name.equals(membersData[i].name)) {return true; /** Post 1: return = true /** for j = 0 to i-1 membersData[j].name != name /** membersData[i].name = name } /** return false; /** Post 2: return = false /** for j = 0 to numberMembers-1 membersData[j].name != name

Verification of IsMember() It is fairly simple to reason that for all pairs of assertions, if the first is true and you reach the next one, it is true also Hence if the precondition holds, and the program terminates, the postcondition will So the contract is valid But we also need to consider termination 6/4/2014Copyright W. Howden29

Termination of isMember() Termination is easy because the loop counts up to a limit from 0 and the precondition /** numberMembers -1 >=0 requires the limit to be larger than the initial value Note: this precondition clause was added during analysis!! I had not thought of this 6/4/2014Copyright W. Howden30

deleteMember() 6/4/2014Copyright W. Howden31 public boolean deleteMember(String name) { int i = 0; while (!(name.equals(membersData[i].name)) & (i <= numberMembers-1)) {++i; } if (i <= numberMembers-1) { for (int j = i; j< numberMembers-1; ++j) { membersData[j]=membersData[j+1]; } --numberMembers; return true; } else {return false; }

deleteMember() - Pre and Post Conditions notation: x means new value of x, versus original or previous value contents stands for the collection of items in the designated data structure Precondition /* for k = 1 to numberMembers-1 membersData[k] non null, membersData.name field is a string /* name is of type string /* numberMembers >=0 Postcondition /** if there exists some k, 1 <= k <= numberMembers – 1 such that memberData[k].name = name /** numberMembers = numberMembers – 1 and /** contents(memberData[j], 1<= j <= numberMembers-1) = contents(memberData[j], 1<= j <= numberMembers) ~ memberData[k] /** if there does not exist some k, 1 <= k <= numberMembers – 1 such that memberData[k].name = name /** numberMembers = numberMembers /** for j = 1 to numberMembers-1, membersData[j] = membersData[j] /** return false 6/4/2014Copyright W. Howden32

Intermediate Assertions All intermediate assertions except –return/exit assertion for second return –final assertion to summarize both return assertions 6/4/2014Copyright W. Howden33

6/4/2014Copyright W. Howden34 public boolean deleteMember(String name) { int i = 0; while (!(name.equals(membersData[i].name)) & (i <= numberMembers-1)) {/** for j = 0 to i, name != membersData[j].name /** i <= numberMembers-1 /** for j = 0 to membersData – 1, membersData[j] = membersData[j] ++i; } if (i <= numberMembers-1) {/** for j = 0 to i-1, name != membersData[j].name /** i <= numberMembers-1 /** name == membersData[i].name for (int j = i; j< numberMembers-1; ++j) { membersData[j]=membersData[j+1]; /** for k = 1 to i-1, membersData[k] =membersData[k]; /** for k = i to j, membersData[k] = membersData[k+1] } /** for k = 1 to i-1, membersData[k] =membersData[k]; /** for k = i to numberMembers-2, membersData[k] = membersData[k+1] --numberMembers; return true; } else {return false; }

Sample Reasoning About First Pre-Return Assertion First part follows directly from the intermediate assertion in the loop Second part follows from the second intermediate assertion plus the following if the loop was entered, then the final value of j on exit must have been numberMembers-2 if we did not enter the loop then i must have been numberMembers-1 so it is vacuously true 6/4/2014Copyright W. Howden35

deleteMember() with Second Pre-Return Assertion 6/4/2014Copyright W. Howden36 public boolean deleteMember(String name) { int i = 0; while (!(name.equals(membersData[i].name)) & (i <= numberMembers-1)) {++i; } if (i <= numberMembers-1) { for (int j = i; j< numberMembers-1; ++j) { membersData[j]=membersData[j+1]; } --numberMembers; return true; } else /** for j = 0 to numberMembers - 1, memberData[j].name != name {return false; }

Sample Reasoning about Second Pre-Return Assertion If we have the case where i is not numberMembers-1 If we use the above along with the first while-loop intermediate assertion, we can get the second pre-return assertion 6/4/2014Copyright W. Howden37

Final Intermediate Assertions Assertion to go just after last } /** return = true /** i <= numberMembers-1 /** membersData[i].name = name /** for k = 1 to i-1 membersData[k] =membersData[k]; /** for k = i to numberMembers-2 membersData[k] = membersData[k+1] /** numberMembers = nuumberMembers - 1; /* or /** return false /** not (i <= numberMembers-1) /** for k = 1 to numberMembers-1 membersData[k].name != name /** for k = 1 to i-1 membersData[k] =membersData[k]; /** numberMembers = numberMembers 6/4/2014Copyright W. Howden38

Continued Reasoning The two pre return intermediate assertions imply the final intermediate assertion The final intermediate assertion gives us the Postcondition 6/4/2014Copyright W. Howden39

Oops? Consider the precondition /* for k = 1 to numberMembers-1 membersData[k] is non null, and membersData.name is a string /* name is of type string /* numberMembers >=0 Now look at the first loop while (!(name.equals(membersData[i].name)) & (i <= numberMembers-1)) {++i; } It is possible to reference membersData[i] with i = numberMembers, and the precondition does not guarantee that it has a non-null value! This is an actual bug that causes a failure 6/4/2014Copyright W. Howden40

Moral of the Story Proofs of correctness forces you to think through the logic of a complex algorithm, but it is error prone for dealing with the details of an actual program In this case, assume that all vectors are infinite, that we can compare a given value with a non-value, etc., and the problem goes away 6/4/2014Copyright W. Howden41

Dynamic Analysis Use Java assertions and testing to verify contracts assert Expression 1 ; assert Expression 1 : Expression 2 ; –If Expression 1 is false then system will throw an error. Value of Expression 2 is returned can be turned off and on using a command line switch 6/4/2014Copyright W. Howden42

Inserting Assertions - Preconditions Precondition is first line of code, consisting of expression in input parameters Public methods should check input and throw an illegal argument exception, rather than have this checked with an assertion methods should protect themselves from bad data even after testing has been completed 6/4/2014Copyright W. Howden43

Inserting Assertions - Postconditions Should occur before each return Use a function to facilitate the situation where there are multiple returns, each requiring the postcondtion 6/4/2014Copyright W. Howden44

Inserting Assertions – Class Invariants True before and after each method Insert in methods as postconditions Class state changed by method call? –No: not necessary to check invariant at beginning of methods –Yes: (e.g. class has public class variables) then include invariant in methods as a precondition 6/4/2014Copyright W. Howden45

Using Assertions with Testing Construct tests using methods such as –black box: normal and oddball inputs –coverage: make sure all statements or branches executed at least once Do not have to manually observe outputs to determine if tests passed if we can rely on the postconditions to catch bad output 6/4/2014Copyright W. Howden46

DS Example - IsMember No precondition assertions, but insert code to confirm validity of input data For output check need to essentially rewrite the code inside a method called by the postcondition assertion –Define a method called noMatch(). 6/4/2014Copyright W. Howden47

Technical Details Defined the method noMatch() inside a new inner class called memberDataProps Want to only create the memberDataProps instance when assertions are turned on (say during testing) so create with an assignment inside a dummy assertion 6/4/2014Copyright W. Howden48

6/4/2014Copyright W. Howden49 public boolean isMember(String name) { class memberDataProps {public boolean noMatch(memberData[] m, int length) { for (i= 0; length-1; ++i;) {if (name.equals(m[i].name)) return false; } return true; } memberDataProps checker; assert ((checker = new memberDataProps()) != null); if (numberMembers-1 < 0) throw new IllegalArgumentException(Out of range parameter); for (int i=0; i <= numberMembers-1; ++i) {if membersData[i] == null throw new IllegalArgumentException(Null param); } for (int i=0; i <= numberMembers-1; ++i) {if (name.equals(membersData[i].name)) {assert name.equals(membersData[i].name); return true; } assert checker.noMatch(membersData, numberMembers); return false; }

Useful? Will use of assertions here lead to defect detection? Having to essentially rewrite the method inside the noMatch() method seems shaky. –maybe it would have the same bugs as the code 6/4/2014Copyright W. Howden50

deleteMember() Could use postconditions that: for false, check that vector items are the same, and numberMembers is unchanged for true, check that the deleted element not in the list, and the contents are the same except for deleted element. Also numberMembers is decremented Document expected loop bounds invariant. With a good set of tests this is what will find the problem 6/4/2014Copyright W. Howden51

Assignment 11 Choose two classes from your phase 1 that you are going to reuse (select non trivial examples) –Prove their correctness using informal assertions –Construct executable assertions and run tests against them 6/4/2014Copyright W. Howden52