CSE 331 Software Design & Implementation Dan Grossman Fall 2014 Lecture 3 – Reasoning About Loops 1CSE 331 Fall 2014.

Slides:



Advertisements
Similar presentations
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Advertisements

Copyright W. Howden1 Programming by Contract CSE 111 6/4/2014.
In this episode of The Verification Corner, Rustan Leino talks about Loop Invariants. He gives a brief summary of the theoretical foundations and shows.
Introduction to Algorithms Quicksort
Semantics Static semantics Dynamic semantics attribute grammars
Reasoning About Code; Hoare Logic, continued
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.
CSE 331 Software Design & Implementation Dan Grossman Winter 2014 Lecture 2 – Reasoning About Code With Logic 1CSE 331 Winter 2014.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION WORKSHEET A Autumn 2011 Today’s Process If you haven’t completed the solution sheet for Worksheet A, please leave.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Recursion. Objectives At the conclusion of this lesson, students should be able to Explain what recursion is Design and write functions that use recursion.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
CS 330 Programming Languages 09 / 16 / 2008 Instructor: Michael Eckmann.
CSC 395 – Software Engineering Lecture 21: Overview of the Term & What Goes in a Data Dictionary.
Describing Syntax and Semantics
CS 106 Introduction to Computer Science I 10 / 15 / 2007 Instructor: Michael Eckmann.
CHAPTER 10 Recursion. 2 Recursive Thinking Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
CS 106 Introduction to Computer Science I 10 / 16 / 2006 Instructor: Michael Eckmann.
While Loops and Do Loops. Suppose you wanted to repeat the same code over and over again? System.out.println(“text”); System.out.println(“text”); System.out.println(“text”);
Computer Science School of Computing Clemson University Discrete Math and Reasoning about Software Correctness Murali Sitaraman
Reading and Writing Mathematical Proofs
1 Inference Rules and Proofs (Z); Program Specification and Verification Inference Rules and Proofs (Z); Program Specification and Verification.
CSI 3125, Axiomatic Semantics, page 1 Axiomatic semantics The assignment statement Statement composition The "if-then-else" statement The "while" statement.
SWE 619 © Paul Ammann Procedural Abstraction and Design by Contract Paul Ammann Information & Software Engineering SWE 619 Software Construction cs.gmu.edu/~pammann/
Reading and Writing Mathematical Proofs Spring 2015 Lecture 4: Beyond Basic Induction.
Reasoning about programs March CSE 403, Winter 2011, Brun.
© Paul Ammann, 2008 Design by Contract Paul Ammann CS/SWE 332.
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.
1/6/20161 CS 3343: Analysis of Algorithms Lecture 2: Asymptotic Notations.
ANU COMP2110 Software Design in 2003 Lecture 10Slide 1 COMP2110 Software Design in 2004 Lecture 12 Documenting Detailed Design How to write down detailed.
CSSE501 Object-Oriented Development. Chapter 10: Subclasses and Subtypes  In this chapter we will explore the relationships between the two concepts.
Dr. Naveed Riaz Design and Analysis of Algorithms 1 1 Formal Methods in Software Engineering Lecture # 26.
Loop Invariants and Binary Search Chapter 4.4, 5.1.
Searching CSE 103 Lecture 20 Wednesday, October 16, 2002 prepared by Doug Hogan.
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.
Zach Tatlock / Winter 2016 CSE 331 Software Design and Implementation Lecture 2 Formal Reasoning.
CS100A, Fall Review of loops 1 CS100A, Fall 1998, Review of Loops and Loop Invariants Some students are still having trouble understanding loop invariants.
Design by Contract. The Goal Ensure the correctness of our software (correctness) Recover when it is not correct anyway (robustness) Correctness: Assertions.
Recursion. Objectives At the conclusion of this lesson, students should be able to Explain what recursion is Design and write functions that use recursion.
Chapter 15 Running Time Analysis. Topics Orders of Magnitude and Big-Oh Notation Running Time Analysis of Algorithms –Counting Statements –Evaluating.
CORRECTNESS ISSUES AND LOOP INVARIANTS Lecture 8 CS2110 – Fall 2014.
© 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.
Correctness issues and Loop invariants
CSE 331 Software Design and Implementation
CSE 374 Programming Concepts & Tools
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
CSE 331 Software Design & Implementation
CSE332: Data Abstractions Lecture 5: Binary Heaps, Continued
CSE 331 Software Design and Implementation
Reasoning About Code; Hoare Logic
Lecture 5 Floyd-Hoare Style Verification
Axiomatic semantics Points to discuss: The assignment statement
Programming Languages 2nd edition Tucker and Noonan
CSE 331 Software Design and Implementation
CSE 331 Software Design & Implementation
Asymptotic complexity Searching/sorting
Predicate Transformers
CSE373: Data Structures & Algorithms Lecture 7: Binary Heaps, Continued Dan Grossman Fall 2013.
Asymptotic complexity
CS100J Lecture 16 Previous Lecture This Lecture Programming concepts
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
CS100J Lecture 16 Previous Lecture This Lecture Programming concepts
Programming Languages 2nd edition Tucker and Noonan
Presentation transcript:

CSE 331 Software Design & Implementation Dan Grossman Fall 2014 Lecture 3 – Reasoning About Loops 1CSE 331 Fall 2014

Reasoning about loops So far, two things made all our examples much easier: 1.When running the code, each statement executed 0 or 1 times 2.(Therefore,) trivially the code always terminates Neither of these hold once we have loops (or recursion) –Will consider the key ideas with while-loops –Introduces the essential and much more general concept of an invariant –Will mostly ignore prove-it-terminates; brief discussion at end CSE 331 Fall 20142

Informal example As before, consider high-level idea before the precise Hoare-triple definitions // assume: x >= 0 y = 0; i=0; // x >= 0 ∧ y = 0 ∧ i = 0 // invariant: y = sum(1,i) while(i != x) { // y = sum(1,i) ∧ i != x i = i+1; // y = sum(1,i-1) y = y+i; // y = sum(1,i-1)+i } // i=x ∧ y = sum(1,i) // assert: y = sum(1,x) CSE 331 Fall 20143

Key lessons To reason about a loop (that could execute any number of iterations), we need a loop invariant The precondition for the loop must imply the invariant –(Precondition stronger than (or equal to) invariant) Invariant plus loop-test-is-true must be enough to show the postcondition of the loop body also implies the invariant (!) Invariant and loop-test-is-false must be enough to show the postcondition of the loop CSE 331 Fall 20144

The Hoare logic Consider just a while-loop (other loop forms not so different) {P} while B S {Q} Such a triple is valid if there exists an invariant I such that: P => I invariant must hold initially {I ∧ B}S{I} body must re-establish invariant (I ∧ !B) => Q invariant must establish Q if test-is-false The loop-test B, loop-body S, and loop-invariant I “fit together”: –There is often more than one correct loop, but with possibly different invariants Note definition “makes sense” even in the zero-iterations case CSE 331 Fall 20145

Example, more precisely CSE 331 Fall {x >= 0} y = 0; i=0; {pre: x >= 0 ∧ y = 0 ∧ i = 0} {inv: y = sum(1,i)} while(i != x) { i = i+1; y = y+i; } {post: i=x ∧ y = sum(1,i)} (so: y = sum(1,x)) {P} while B S {Q} P => I invariant must hold initially {I ∧ B}S{I} body must re-establish invariant (I ∧ !B) => Q invariant must establish Q if test-is-false

A different approach A different loop has a different invariant CSE 331 Fall {x >= 0} y = 0; i=1; {pre: x >= 0 ∧ y = 0 ∧ i = 1} {inv: y = sum(1,i-1)} while(i != x+1) { y = y+i; i = i+1; } {post: i=x+1 ∧ y = sum(1,i-1)} (so: y = sum(1,x))

And find bugs And this third approach doesn’t do what we want CSE 331 Fall {x >= 0} y = 0; i=1; {pre: x >= 0 ∧ y = 0 ∧ i = 1} {inv: y = sum(1,i-1)} while(i != x) { y = y+i; i = i+1; } {post: i=x ∧ y = sum(1,i-1)} (so: y = sum(1,x))

More bugs And this approach has an invalid Hoare triple hidden in it CSE 331 Fall {x >= 0} y = 0; i=0; {pre: x >= 0 ∧ y = 0 ∧ i = 0} {inv: y = sum(1,i)} while(i != x) { y = y+i; i = i+1; // invariant not satsified – why? } {post: i=x ∧ y = sum(1,i)}

Neither too strong nor too weak If loop invariant is too strong, it could be false! –Won’t be able to prove it holds either initially or after loop-body If loop invariant is too weak, it could –Leave the post-condition too weak to prove what you want –And/or be impossible to re-establish after the loop body This is the essence of why there is no complete automatic procedure for conjuring a loop-invariant –Requires thinking (or, sometimes, “guessing”) –Often while writing the code –If proof doesn’t work, invariant or code or both may need work There may be multiple invariants that “work” (neither too strong nor too weak), with some easier to reason about than others CSE 331 Fall

A methodology Fortunately, programming is creative and inventive! Here, this means coming up with a loop and its invariant Won’t advocate a hard-and-fast rule, but do want to avoid the natural approach of “always code first, dream up invariant second” Instead, often surprisingly effective to go in this order: 1.Think up the invariant first, have it guide all other steps (!) What describes the milestone of each iteration? 2.Write a loop body to maintain the invariant 3.Write the loop test so false-implies-postcondition 4.Write initialization code to establish invariant CSE 331 Fall

Example Set max to hold the largest value in array items 1.Think up the invariant first, have it guide all other steps –Invariant: max holds largest value in range 0..k-1 of items –Other approaches possible: Homework 2 CSE 331 Fall

Example Set max to hold the largest value in array items 2.Write a loop body to maintain the invariant {inv: max holds largest value in items[0..k-1]} while( ) { // inv holds if(max < items[k]) { max = items[k]; // breaks inv temporarily } else { // nothing to do } // max holds largest value in items[0..k] k = k+1; // invariant holds again } CSE 331 Fall

Example Set max to hold the largest value in array items 3.Write the loop test so false-implies-postcondition {inv: max holds largest value in items[0..k-1]} while(k != items.size) { // inv holds if(max < items[k]) { max = items[k]; // breaks inv temporarily } else { // nothing to do } // max holds largest value in items[0..k] k = k+1; // invariant holds again } CSE 331 Fall

Example Set max to hold the largest value in array items 4.Write initialization code to establish invariant k=1; max = items[0]; {inv: max holds largest value in items[0..k-1]} while(k != items.size) { … } CSE 331 Fall

Edge case Our initialization code has a precondition: items.size > 0 {items.size > 0} k=1; max = items[0]; {inv: max holds largest value in items[0..k-1]} while(k != items.size) { … } Such a (specified!) precondition may be appropriate Else need a different postcondition (“if size is 0, …”) and a conditional that checks for the empty case –Or the Integer.MIN_VALUE “trick” and logical reasoning Neat: Precise preconditions should expose all this to you! CSE 331 Fall

More examples Here: –Quotient and remainder –“Dutch national flag problem” (like Homework 0) More in reading notes: –Reverse an array (have to refer to “original” values) –Binary search (invariant about range of array left to search) More on Homework 2: –Enjoy! CSE 331 Fall

Quotient and remainder Set q to be the quotient of x / y and r to be the remainder Pre-condition: x > 0 ∧ y > 0 Post-condition: q*y + r = x ∧ r >= 0 ∧ r < y A possible loop invariant: q*y + r = x ∧ r >= 0 A loop body that preserves the invariant: q = q + 1; r = r – y; The loop test that given the invariant implies the post: y <= r Initialization to establish invariant: q = 0; r = x; CSE 331 Fall

Put it all together {x > 0 ∧ y > 0} // can this be weakened? r = x; q = 0; {inv: q*y + r = x ∧ r >= 0 } while (y <= r) { q = q + 1; r = r – y; } {q*y + r = x ∧ r >= 0 ∧ r < y} CSE 331 Fall

Dutch National Flag (classic example) Given an array of red, white, and blue pebbles, sort the array so the red pebbles are at the front, white are in the middle, and blue are at the end –[Use only swapping contents rather than “count and assign”] CSE 331 Fall Edsgar Dijkstra

Pre- and post-conditions Precondition: Any mix of red, white, and blue Postcondition: –Red, then white, then blue –Number of each color same as in original array CSE 331 Fall Mixed colors: red, white, blue RedWhiteBlue

Some potential invariants Any of these four choices can work, making the array more-and- more sorted as you go: Middle two slightly better because at most one swap per iteration instead of two CSE 331 Fall RedWhiteBlueMixed RedWhiteBlueMixed RedWhiteBlue Mixed RedWhiteBlueMixed

More precise, and then some code Precondition P : arr contains r reds, w whites, and b blues Postcondition: P ∧ 0 <= i <= j <= arr.size ∧ arr[0..i-1] is red ∧ arr[i..j-1] is white ∧ arr[j..arr.size-1] is blue Invariant: P ∧ 0 <= i <= j <= k <= arr.size ∧ arr[0..i-1] is red ∧ arr[i..j-1] is white ∧ arr[k..arr.size-1] is blue Initializing to establish the invariant (could do before or after body): i=0; j=0; k=arr.size; CSE 331 Fall

The loop test and body i j k while(j!=k) { if(arr[j] == White) { j = j+1; } else if (arr[j] == Blue) { swap(arr,j,k-1); k = k-1; } else { // arr[j] == Red swap(arr,i,j) i = i + 1; j = j+1; } } CSE 331 Fall RedWhiteBlueMixed void swap(int[] x, int y, int z) { int tmp = x[y]; x[y] = x[z]; x[z] = tmp; }

Aside: swap Reading notes write swap(a[i],a[j]) and such This is not implementable in Java –But fine pseudocode –Great exercise: Write a coherent English paragraph why it is not implementable in Java (i.e., does not do what you want) You can implement swap(a,i,j) in Java –So previous slide and Homework 2 do it that way CSE 331 Fall

When to use proofs for loops Most loops are so “obvious” that proofs are, in practice, overkill –for(String name : friends) {…} Use logical reasoning when intermediate state (invariant) is unclear or edge cases are tricky or you need inspiration, etc. Use logical reasoning as an intellectual debugging tool –What exactly is the invariant? –Is it satisfied on every iteration? –Are you sure? Write code to check? –Did you check all the edge cases? –Are there preconditions you did not make explicit? CSE 331 Fall

Termination Two kinds of loops –Those we want to always terminate (normal case) –Those that may conceptually run forever (e.g., web-server) So, proving a loop correct usually also requires proving termination –We haven’t been proving this: might just preserve invariant forever without test ever becoming false –Our Hoare triples say if loop terminates, postcondition holds How to prove termination (variants exist): –Map state to a natural number somehow (just “in the proof”) –Prove the natural number goes down on every iteration –Prove test is false by the time natural number gets to 0 CSE 331 Fall

Termination examples Quotient-and-remainder: r (starts positive, gets strictly smaller) Binary search: size of range still considered Dutch-national-flag: size of range not yet sorted ( k-j ) Search in a linked list: length of list not yet considered –Don’t know length of list, but goes down by one each time… –… unless list is cyclic in which case, termination not assured CSE 331 Fall