Automatic Discovery of Software Contract Work in progress Yishai Feldman, Leon Gendler.

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

Extended Static Checking for Java Cormac Flanagan K. Rustan M. Leino Mark Lillibridge Greg Nelson James B. Saxe Raymie Stata Compaq SRC 18 June 2002 PLDI02,
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 1 Summer school on Formal Models.
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 0 Summer school on Formal Models.
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Copyright W. Howden1 Programming by Contract CSE 111 6/4/2014.
Design By Contract Using JMSAssert.
Semantics Static semantics Dynamic semantics attribute grammars
ICE1341 Programming Languages Spring 2005 Lecture #6 Lecture #6 In-Young Ko iko.AT. icu.ac.kr iko.AT. icu.ac.kr Information and Communications University.
Reasoning About Code; Hoare Logic, continued
Hoare’s Correctness Triplets Dijkstra’s Predicate Transformers
Chair of Software Engineering OOSC - Summer Semester Object-Oriented Software Construction Bertrand Meyer.
1 University of Toronto Department of Computer Science © 2001, Steve Easterbrook Lecture 10: Formal Verification Formal Methods Basics of Logic first order.
FIT FIT1002 Computer Programming Unit 19 Testing and Debugging.
Partial correctness © Marcelo d’Amorim 2010.
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.
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/22 Programs : Semantics and Verification Charngki PSWLAB Programs: Semantics and Verification Mordechai Ben-Ari Mathematical Logic for Computer.
Avoiding Exponential Explosion: Generating Compact Verification Conditions Cormac Flanagan and James B. Saxe Compaq Systems Research Center With help from.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
1 Specifying Object Interfaces. 2 Major tasks in this stage: --are there any missing attributes or operations? --how can we reduce coupling, make interface.
Hoare-style program verification K. Rustan M. Leino Guest lecturer Rob DeLine’s CSE 503, Software Engineering University of Washington 26 Apr 2004.
Chair of Software Engineering ATOT - Lecture 12, 12 May Advanced Topics in Object Technology Bertrand Meyer.
ECI 2007: Specification and Verification of Object- Oriented Programs Lecture 1.
Houdini: An Annotation Assistant for ESC/Java Cormac Flanagan and K. Rustan M. Leino Compaq Systems Research Center.
Software Reliability Methods Sorin Lerner. Software reliability methods: issues What are the issues?
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.
From last time S1: l := new Cons p := l S2: t := new Cons *p := t p := t l p S1 l p tS2 l p S1 t S2 l t S1 p S2 l t S1 p S2 l t S1 p L2 l t S1 p S2 l t.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Dr. Muhammed Al-Mulhem 1ICS ICS 535 Design and Implementation of Programming Languages Part 1 Fundamentals (Chapter 4) Axiomatic Semantics ICS 535.
Well-cooked Spaghetti: Weakest-Precondition of Unstructured Programs Mike Barnett and Rustan Leino Microsoft Research Redmond, WA, USA.
Software Verification Bertrand Meyer Chair of Software Engineering Lecture 2: Axiomatic semantics.
Describing Syntax and Semantics
Jonathan Kuhn Robin Mange EPFL-SSC Compaq Systems Research Center Flanagan, Leino, Lillibridge, Nelson, Saxe and Stata.
Software Engineering Prof. Dr. Bertrand Meyer March 2007 – June 2007 Chair of Software Engineering Static program checking and verification Slides: Based.
Extended Static Checking for Java  ESC/Java finds common errors in Java programs: null dereferences, array index bounds errors, type cast errors, race.
Low-Level Detailed Design SAD (Soft Arch Design) Mid-level Detailed Design Low-Level Detailed Design Design Finalization Design Document.
ISBN Chapter 3 Describing Semantics -Attribute Grammars -Dynamic Semantics.
CS 363 Comparative Programming Languages Semantics.
OOSC - JMSAssert. Design By Contract A powerful technique for writing reliable software. Specifying the software purpose with the implementation. Key.
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.
Chapter 3 Part II Describing Syntax and Semantics.
COP4020 Programming Languages Introduction to Axiomatic Semantics Prof. Robert van Engelen.
Extended Static Checking for Java Cormac Flanagan Joint work with: Rustan Leino, Mark Lillibridge, Greg Nelson, Jim Saxe, and Raymie Stata.
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.
Principle of Programming Lanugages 3: Compilation of statements Statements in C Assertion Hoare logic Department of Information Science and Engineering.
PROGRAMMING PRE- AND POSTCONDITIONS, INVARIANTS AND METHOD CONTRACTS B MODULE 2: SOFTWARE SYSTEMS 13 NOVEMBER 2013.
Institute for Applied Information Processing and Communications (IAIK) – Secure & Correct Systems 1 Static Checking  note for.
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.
Extended Static Checking for Java Cormac Flanagan Joint work with: Rustan Leino, Mark Lillibridge, Greg Nelson, Jim Saxe, and Raymie Stata Compaq Systems.
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.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
CSE 374 Programming Concepts & Tools Hal Perkins Fall 2015 Lecture 17 – Specifications, error checking & assert.
Extended Static Checking for Java
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Programming Languages 2nd edition Tucker and Noonan
Hoare-style program verification
Java Modeling Language (JML)
The Zoo of Software Security Techniques
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
Programming Languages 2nd edition Tucker and Noonan
COP4020 Programming Languages
Presentation transcript:

Automatic Discovery of Software Contract Work in progress Yishai Feldman, Leon Gendler

Design By Contract Precondition An obligation of the consumer (client) A set of assertions to be ensured before executing a program part Postcondition An obligation of the provider (server) A set of conditions to be fulfilled after executing a program part Invariant A set of conditions concerning the state of the class Ensured to hold before and after each class operation.

Design By Contract Reliability Avoid unexpected inputs and results Expresses and validates correctness arguments Make sure you know what your code does Testing Contract violation means a bug Documentation Express the input and outcome of each class method

Contract A set of pre- and post conditions for each operation provided by a component and an invariant for the whole class. Ensuring the precondition when requesting an operation, guarantees the provider will make the postcondition true at its end.

Contract Example (top >= 0 && top = 0 && top < max)*/ (sz > (max == sz && elems != null) */ class Stack { private Object[] elems; private int top, max; (sz > (max == sz && elems != null) */ public MyStack(int sz) { max = sz; elems = new Object[sz]; } (top == $prev (top) + 1) && elems[top-1] == obj */ (top == $prev (top) + 1) && elems[top-1] == obj */ public void push(Object obj) { elems[top++] = obj; } (top == $prev (top) - 1) && $ret == elems[top] */ (top == $prev (top) - 1) && $ret == elems[top] */ public Object pop() { return elems[--top]; } ($ret == (top == max)) */ ($ret == (top == max)) */ public boolean isFull() { return top == max; } ($ret == (top == 0)) */ ($ret == (top == 0)) */ public boolean isEmpty() { return top == 0; } }

Research Purpose To find a proper contract for a given class by performing static program analysis. The contract may not be complete, there may be pre/post conditions that will not be found The contract will (?) be correct. Discover from the code itself the conditions for its correctness (preconditions) No intention to verify the correctness of a given piece of code. Describe the code’s outcome and the claims about the object’s state at end of execution (postconditions).

Example public synchronized boolean addAll(int index, Collection c) { if (index elementCount) throw new ArrayIndexOutOfBoundsException(index); int numNew = c.size(); ensureCapacityHelper(elementCount + numNew); int numMoved = elementCount - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); Iterator e = c.iterator(); for (int i = 0; i < numNew; i++) elementData[index++] = e.next(); elementCount += numNew; return numNew != 0; } elementData != null elementCount <= elementData.length() elementData.length() <= $pre(elementCount) + c.size() forall i, 0 <= i < c.size(): // $prev(elementData[index + i] = //elementData[index + i + c.size()] index >= 0 index <= elementCount c != null

Verification Condition A logical expression representing a program part. Proving the VC to be correct, proves the program part to be correct. Program verification: Annotate program with assertions and loop invariants (manually). Build all VCs by traversing the annotated program. If the VC is correct then the program stands correct according to the given assertions.

Mechanizing Program Verification Specification to be proved + Loop Invariants Human expert Annotated specification VC Generator Set of logic statements (VC’s) Theorem Prover Simplified set of verif. cond. End of proof Human Expert

Hoare Triplets {P} S {Q} - Starting at state {P} and performing S will bring us to state {Q} Weakest Precondition: wp(S, Q): The weakest initial state {P} in which after performing S will bring us to state {Q} WLP(S, Q): Doesn’t ensure termination Strongest Postcondition SP(S, P): The strongest state {Q} which can be achieved starting at {P} and performing S

Weakest? Strongest? A is stronger than B:A  B A is weaker than B:B  A The weakest condition: True The strongest condition:False

The stronger {P} means less cases to handle, easier job for S {False} S {…}: The easiest job - The customer is always wrong, we can do whatever we want. We need to ask S to work with the weakest {P} The least restriction on the input The Stronger {Q} means more results {…} S {True}: Second Best - We can do whatever we want, but must terminate We expect S to reach the strongest {Q} The maximum the operation can achieve {P} S {Q}: Weakest? Strongest?

Precondition Computation Use Weakest Precondition method to calculate preconditions. Start with the weakest condition : True Traverse the code bottom-up and push the condition through all program instructions. Each command can add to the precondition.

Weakest Precondition wp(x := e, Post) = Post(x := e) Every free occurrence of x in postcondition P is replaced by e. wp(S1;S2, Post) = wp(S1, wp(S2, Post)) Calculate the WP bottom up wp(if B then S1 else S2, Post) = B  wp(S1, Post)   B  wp(S2, Post) wp(while B do S1, Post) =  B  Post  B  wp(while B do S1, wp(S1, Post)) L(i) =  B  Post  B  wp(L(i-1))

Automatic Discovery of Software Contracts Translate the source code into a structural representation (the Plan Calculus). Use a library of structural elements and their contract (assertions) to assign to each structural element its pre/post conditions. Propagate the assertions upwards and downwards through the plan to produce the preconditions and the postconditions. (V.C. generation) Add knowledge by applying heuristics of frequent code Simplify expressions

Looking for a contract Practical Something the programmer can work with A starting point for the programmer to check for possible bugs. Must contain relevant data No local method variables Class members and input variables Must be correct, but ‘almost’ also counts Completeness is impossible

Implementation Input: a Java class source code Translate the Java class into a plan representation Code written in Java using Barat Barat: A front-end for Java to support static analysis of Java programs. Builds a complete abstract syntax tree from Java source code files, enriched with name and type analysis information. Generate a Lisp representation of a plan. Traverse the plan generating the contract. Use predefined spec’s assertion and known methods’ library Use ACL2 Theorem Prover to simplify generated logical expressions and to check possible contract assumptions.

ACL2 An automated reasoning system Developed (for the first 9 years) at Computational Logic, Inc. and (from January, 1997) at the University of Texas at Austin. The successor to the Nqthm (or Boyer-Moore) logic and proof system A Computational Logic for Applicative Common Lisp An automated theorem prover or proof checker A competent user can utilize the ACL2 system to discover proofs of theorems stated in the ACL2 logic or to check previously discovered proofs

WP Example {(and (>= i 0) (< i 5))} int j = i * 2; {(and (not (eq a nil)) (>= i 0) (< i (len a)))} a[i] = j; {t} int [] a = new int [5]; {(let ((j (* 2 i))) (and (not (eq a nil)) (>= i 0) (< i (len a)))} {(and (not (eq a nil)) (>= i 0) (< i (len a))), (not (eq a nil)) (eq (len a) 5))} {(and (>= 5 0) (>= i 0) (< i 5))} int foo (int i) { int [] a = new int[5]; int j = i*2; a[i] = j;... }

Plan Calculus A structural, high level representation Manipulation of local variables is represented as Data Flow Representation of Control Flow which can be parallel. Spec Types: IO Spec Test Spec Join Spec

Condition Structure Outer Failure Success Outer-wp Join Test Success-wp Failure-wp  Test  Failure-wp  Test  Success-wp

negate-if-negative < Join FS Test FS int abs (int x) { If (x < 0) { x = -x; } return x; } - x

Loops Traverse the loop several times until: Either a fixed-point in the contract is reached Or a fixed number of iteration Usually, the first traversal contributes most of the information. Try to identify special behavior: well-known loop structures such as array or range iteration.

Loop structure feedback body outer Body-wp Feedback-wpOuter-wp Join Test

For example Test FS Join FS < aset ++ i i i i i = init limit for (i=init; i<limit; i++) {... a[i] = x... } a a a a x

Vector.addAll(int, collection) public synchronized boolean addAll(int index, Collection c) { if (index elementCount) throw new ArrayIndexOutOfBoundsException(index); int numNew = c.size(); ensureCapacityHelper(elementCount + numNew); int numMoved = elementCount - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); Iterator e = c.iterator(); int limit = index + numNew; for (int i = index; i < limit; i++) elementData[i] = e.next(); elementCount += numNew; return numNew != 0; }

Precondition of Vector.addAll(int, collection) (AND (NOT (OR (< INDEX 0) (< ELEMENTCOUNT INDEX))) C (OR (NOT (< 0 (+ ELEMENTCOUNT (- INDEX)))) (AND (NOT (< (+ INDEX NUMNEW) 0)) ELEMENTDATA (<= (+ INDEX ELEMENTCOUNT (- INDEX)) (LEN ELEMENTDATA)) (<= (+ INDEX NUMNEW ELEMENTCOUNT (- INDEX)) (LEN ELEMENTDATA)))))... (AND (>= INDEX 0) (>= ELEMENTCOUNT INDEX) ;; If (…) Throw {…} C;; c.size() (IMPLIES ( 0)… (AND (>= (+ INDEX NUMNEW) 0) ;; System.arrayCopy ELEMENTDATA (<= ELEMENTCOUNT (LEN ELEMENTDATA)) (<= (+ NUMNEW ELEMENTCOUNT) (LEN ELEMENTDATA)))))

Precondition of Vector.addAll(int, collection) (AND (>= INDEX 0) (>= ELEMENTCOUNT INDEX) C (IMPLIES (< 0 (- ELEMENTCOUNT INDEX)) (AND (>= (+ INDEX NUMNEW) 0) ELEMENTDATA (<= ELEMENTCOUNT (LEN ELEMENTDATA)) (<= ELEMENTCOUNT (LEN ELEMENTDATA)) (<= (+ NUMNEW ELEMENTCOUNT) (LEN ELEMENTDATA))) (<= (+ NUMNEW ELEMENTCOUNT) (LEN ELEMENTDATA))))) Class Invariant Postcondition of ensureCapacityHelper(int capacity): (LEN ELEMENTDATA) >= capacity

Full Precondition (AND (NOT (OR (< INDEX 0) (< ELEMENTCOUNT INDEX))) C (OR (NOT (< 0 (+ ELEMENTCOUNT (- INDEX)))) (AND (NOT (< (+ INDEX NUMNEW) 0)) ELEMENTDATA (<= (+ INDEX ELEMENTCOUNT (- INDEX)) (LEN ELEMENTDATA)) (<= (+ INDEX NUMNEW ELEMENTCOUNT (- INDEX)) (LEN ELEMENTDATA)) (OR (NOT (< INDEX LIMIT)) (AND E (< 0 INDEX) (AND E (< 0 INDEX) (< INDEX (LEN ELEMENTDATA)) (< INDEX (LEN ELEMENTDATA)) (OR (NOT (< (+ 1 INDEX) LIMIT)) (OR (NOT (< (+ 1 INDEX) LIMIT)) (< (+ 1 INDEX) (LEN ELEMENTDATA))))) )) (< (+ 1 INDEX) (LEN ELEMENTDATA))))) )) (COND ((< 0 (+ ELEMENTCOUNT (- INDEX))) T) ((< INDEX LIMIT) (AND E ELEMENTDATA (< 0 INDEX) (< INDEX (LEN ELEMENTDATA)) (OR (NOT (< (+ 1 INDEX) LIMIT)) (< (+ 1 INDEX) (LEN ELEMENTDATA))))) (T T)))

Cleaning the result The precondition may contain irrelevant data internal implementation The precondition should contain only global and input variables.

Adding more knowledge Serial traversal: Most commonly used loop to traverse an array (any serial traversal) Adding the calculation of the last loop traversal Add special information: For (i = init; i < limit; i++) {... NO BREAK...}: Assert init < limit  "First execution"  i=limit  #=limit-init Assert  (init < limit)  "No execution"  i = init  # = 0

Serial Traversal for(i = init; i < limit; i++) { … a[i] = … } Easy to find: 0  init < a.len Better: a.length()  limit Method: Add i = limit (the last value of i) as a postcondition of the loop. Compute the loop precondition based on: L(k) - the postcondition computed so far i = limit - the value of i on the last iteration

for(i=0; i<n; i++) {… a[i] …} L(0) = outer, L(i) =  p  L(0)  p  wp(S,L(i-1)) L(1) = i  n  outer  i<n  wp(…a[i]…, wp(i++, L(0))) L(1) = i  n  outer  i < n  0  i < a.len L(2) = i  n  outer  i<n  wp(…a[i]…;i++, L(1)) L(2) = i  n  outer  i<n  wp(…a[i]…;i++, i  n  outer  i < n  0  i < a.len) L(2) = i  n  outer  i = n-1  wp(outer)  i < n  0  i < a.len  i+1 < n  0  i+1 < a.len L(k) = i  n  outer  […  i=n-k  wp k-1 (outer)  …]  [i < n  0  i < a.len)  … i+k < n  0  i+k-1 < a.len)]

Wp(loop, i=0) 0 < n  0  0 < a.len 1 < n  0  1 < a.len … k < n  0  k < a.len wp(…a[i];i++…, L(k)  i = n)) (after loop exit)  wp(…a[i];i++…, wp(i++, L(k)  i = n))  wp(…a[i], L(k) i = i+1  i+1 = n  0  i < a.len  L(k) i = i+1  i+1 = n  0  n-1 < a.len  L(k) i = i+1

Computing Postconditions Similar computation as in Preconditions. Possible improvement: use the already computed preconditions as an initial value

Class Invariant Finding candidates: Assertions regarding class members Assertions appearing in more that one method’s preconditions. Assertions appearing in pre and post conditions Checking candidate assertions: The assertion doesn’t effect contract of methods it is not part of their contract.

Related Research ESC/Java Statically detects common errors such as null pointer references Programmer adds annotations (assertion statements) ESC/Java issues warnings about annotations which cannot be verified. Translates the program into V.C.s and tries to prove them. Houdini Guesses a candidate set of annotations and uses ESC/Java to prove them correct

Block diagram

ESC example class Bag { int[] a; int n; Bag(int[] input) { n = input.length; a = new int[n]; System.arraycopy(input, 0, a, 0, n); } int extractMin() { int m = Integer.MAX_VALUE; int mindex = 0; for (int i = 0; i < n; i++) { if (a[i] < m) { mindex = i; m = a[i]; } n--; a[mindex] = a[n]; return m; }

escjava Bag.java

ESC example class Bag { non_null */ int[] a; int n; invariant 0 <= n && n <= a.length; requires input != null; Bag(int[] input) { n = input.length; a = new int[n]; System.arraycopy(input, 0, a, 0, n); } requires n >= 1; int extractMin() { int m = Integer.MAX_VALUE; int mindex = 0; for (int i = 0; i < n; i++) { if (a[i] < m) { mindex = i; m = a[i]; } n--; a[mindex] = a[n]; return m; }

Blow-up from assignment rule wp(x := e,Q) = Q(x  e) Q(x  e) may contain many copies of e Sequential composition of assignment statements may yield exponentially large VC, e.g. wp( b=a+a ; c=b+b ;... ; z=y+y, z>0)

References Bertrand Meyer, Object-Oriented Software Construction, 2nd edition, Prentice-Hall, Charles Rich, Richard C. Waters, The Programmer's Apprentice, Addison-Wesley, November Matt Kaufmann, Panagiotis Manolios, and J Strother Moore, Computer-Aided Reasoning: An Approach, Kluwer Academic Publishers, June, 2000 Edsger W. Dijkstra, Carel S. Scholten Predicate Calculus and Program Semantics, Springer-Verlag, July Richard C. Waters, "A Method for Analyzing Loop Programs", IEEE Transactions on Software Engineering, vol. 5 pp , May Guy L. Steele Jr., Common Lisp: The Language, 2nd edition, Butterworth- Heinemann, December David L. Detlefs, K. Rustan M. Leino, Greg Nelson, and James B. Saxe. "Extended Static Checking". Research Report 159, Compaq Systems Research Center, December, 1998.