1 / 44

A reminder

A reminder. Programming Fundamentals 21 Feliks Klu ź niak. Operational thinking is no good: there are too many paths. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons.

spence
Download Presentation

A reminder

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. A reminder Programming Fundamentals 21 Feliks Kluźniak A reminder

  2. Operational thinking is no good: there are too many paths. A reminder

  3. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. A reminder

  4. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. “Testing can show the presence of errors, but not their absence.” E. W. Dijkstra A reminder

  5. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. So we must be able to reason about programs as static entities. A reminder

  6. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. So we must be able to reason about programs as static entities. The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. A reminder

  7. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. So we must be able to reason about programs as static entities. The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. This allows us to “dispose of history”: we don’t care how the program got here, we only care about what must be true when the program is here. A reminder

  8. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. So we must be able to reason about programs as static entities. The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. This allows us to “dispose of history”: we don’t care how the program got here, we only care about what must be true when the program is here. Of course, at any given (reachable) point there is an infinite number of correct assertions: we are interested only in those that have something to do with our purpose! A reminder

  9. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. So we must be able to reason about programs as static entities. The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. The effective and precise way to characterize a set of state is to use predicate calculus. A reminder

  10. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. So we must be able to reason about programs as static entities. The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. The effective and precise way to characterize a set of state is to use predicate calculus. You may use English as well, but it is much harder to make it sufficiently precise and concise, so in the lectures I must use predicates. A reminder

  11. Operational thinking is no good: there are too many paths. The usefulness of testing is limited, for the same reasons. So we must be able to reason about programs as static entities. The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. The effective and precise way to characterize a set of state is to use predicate calculus. You may use English as well, but it is much harder to make it sufficiently precise and concise, so in the lectures I must use predicates. You will find that even elementary knowledge of predicate calculus (i.e., “mathematical logic”) is useful in all walks of life. A reminder

  12. Operational thinking is no good: there are too many paths. • The usefulness of testing is limited, for the same reasons. • So we must be able to reason about programs as static entities. • The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. • The effective and precise way to characterize a set of state is to use predicate calculus. • Assertions about loops are a special case: consider “unrolling” the loop • while B do • S • od • say, three times: • S % P0 • S % P1 • S % P2 A reminder

  13. Operational thinking is no good: there are too many paths. • The usefulness of testing is limited, for the same reasons. • So we must be able to reason about programs as static entities. • The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. • The effective and precise way to characterize a set of state is to use predicate calculus. • Assertions about loops are a special case: consider “unrolling” the loop • while B do • S • od • say, three times: • S % P0 • S % P1 • S % P2 The assertions P0, P1 and P2 had better have something in common: otherwise we would have to carry out a separate reasoning for each possible unrolling of the loop (i.e., each possible number of repetitions of S. A reminder

  14. Operational thinking is no good: there are too many paths. • The usefulness of testing is limited, for the same reasons. • So we must be able to reason about programs as static entities. • The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. • The effective and precise way to characterize a set of state is to use predicate calculus. • Assertions about loops are a special case: consider “unrolling” the loop • while B do • S • od • say, three times: • S % P0 • S % P1 • S % P2 The assertions P0, P1 and P2 had better have something in common: otherwise we would have to carry out a separate reasoning for each possible unrolling of the loop (i.e., each possible number of repetitions of S. Hence the idea of an invariant: an assertion that always holds before and after S. A reminder

  15. Operational thinking is no good: there are too many paths. • The usefulness of testing is limited, for the same reasons. • So we must be able to reason about programs as static entities. • The way to do this is to use assertions, which characterize the set of states in which the program must be at a given point. • The effective and precise way to characterize a set of state is to use predicate calculus. • Assertions about loops are a special case: consider “unrolling” the loop • while B do • S • od • say, three times: • S % P0 • S % P1 • S % P2 The assertions P0, P1 and P2 had better have something in common: otherwise we would have to carry out a separate reasoning for each possible unrolling of the loop (i.e., each possible number of repetitions of S. Hence the idea of an invariant: an assertion that always holds before and after S. Again, there is an infinite number of these: we are interested in one that is relevant to our purpose. A reminder

  16. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, provided the loop terminates. A reminder

  17. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • We have seen that in general this is our only tool for reasoning about loops. Remember the black and white balls? A reminder

  18. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • We have seen that in general this is our only tool for reasoning about loops. Remember the black and white balls? • BTW, this is the only theorem in our course, so it’s a good idea to be aware of it… A reminder

  19. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • We have seen that in general this is our only tool for reasoning about loops. Remember the black and white balls? • How do we find the “interesting invariant”? The only effective way is to start with finding the invariant, then write the loop. A reminder

  20. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • We have seen that in general this is our only tool for reasoning about loops. Remember the black and white balls? • This theorem leads to the following standard method of writing a loop: A reminder

  21. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. R A reminder

  22. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. P R A reminder

  23. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that [ P and not B implies R ] . P R P and not B A reminder

  24. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that [ P and not B implies R ] . • We find a way to achieve termination while keeping P invariant: this will get us to R ! P R P and not B A reminder

  25. The fundamental invariance theorem for the iterative construct • (aka The main theorem of Computing Science) • Let P be an invariant of the statement S. • IfPis true just before the loop • while B do • S • od • thennot B and Pwill be true just after the loop, • provided the loop terminates. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that [ P and not B implies R ] . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • We don’t care about the exact path, which is a BIG WIN . P R P and not B

  26. In some simple cases we may write loops that are so trivial that • this method is not really necessary: our operational intuition is good • enough. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • We don’t care about the exact path, which is a BIG WIN . P R P and not B

  27. In some simple cases we may write loops that are so trivial that • this method is not really necessary: our operational intuition is good • enough. • But even in those cases it is good practice to think (and comment!): • ”What is the invariant?”, ”What is the termination argument?”. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • We don’t care about the exact path, which is a BIG WIN . P R P and not B

  28. In some simple cases we may write loops that are so trivial that • this method is not really necessary: our operational intuition is good • enough. • But even in those cases it is good practice to think (and comment!): • ”What is the invariant?”, ”What is the termination argument?”. • This will keep us out of harm’s way, and practice makes perfect. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • We don’t care about the exact path, which is a BIG WIN . P R P and not B

  29. In some simple cases we may write loops that are so trivial that • this method is not really necessary: our operational intuition is good • enough. • But even in those cases it is good practice to think (and comment!): • ”What is the invariant?”, ”What is the termination argument?”. • This will keep us out of harm’s way, and practice makes perfect. • It is not difficult to find examples when disregarding the method • leads us into blind alleys: • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • We don’t care about the exact path, which is a BIG WIN . P R P and not B

  30. In some simple cases we may write loops that are so trivial that • this method is not really necessary: our operational intuition is good • enough. • But even in those cases it is good practice to think (and comment!): • ”What is the invariant?”, ”What is the termination argument?”. • This will keep us out of harm’s way, and practice makes perfect. • It is not difficult to find examples when disregarding the method • leads us into blind alleys: • Challenge: Without looking at the slides entitled • ”Binary search” write a binary search program and • convince yourself (by testing) that it works in all cases. • This theorem leads to the following standard method of writing a loop: • We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • We don’t care about the exact path, which is a BIG WIN . P R P and not B

  31. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • When we write loops that process arrays, we very often have predicates of the following form: • ( A j : i =< j < k : P( j ) ) A reminder

  32. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • When we write loops that process arrays, we very often have predicates of the following form: • ( A j : i =< j < k : P( j ) ) • P( j ) is some predicate in which j is a free variable, e.g., a[ j ] = 0 . A reminder

  33. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • When we write loops that process arrays, we very often have predicates of the following form: • ( A j : i =< j < k : P( j ) ) • P( j ) is some predicate in which j is a free variable, e.g., a[ j ] = 0 . • In the entire expression above, j is a bound variable, but i and k are free variables, so we often write • Q( i, k ) : ( A j : i =< j < k : P( j ) ) A reminder

  34. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • When we write loops that process arrays, we very often have predicates of the following form: • ( A j : i =< j < k : P( j ) ) • P( j ) is some predicate in which j is a free variable, e.g., a[ j ] = 0 . • In the entire expression above, j is a bound variable, but i and k are free variables, so we often write • Q( i, k ) : ( A j : i =< j < k : P( j ) ) • This just means that we give this predicate a name, Q, and point out that i and k are its free variables: Q( i, k ) might be true of false depending on the values of i and k . A reminder

  35. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) A reminder

  36. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • For example, • ( A i : i =< j < k : a[ j ] = 0 ) • is just an abbreviation for • true and a[ i ] = 0 and a[ i + 1 ] = 0 and ... and a[ k – 1 ] = 0 A reminder

  37. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • An important point to remember is that this predicate is true when i >= k, i.e., when the range is empty, i.e., when there is no j that satisfies i =< j < k . A reminder

  38. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • If we have • ( A j : i =< j < k : P( j ) ) and ( A j : k =< j < m : P( j ) ) • then this is equivalent to • ( A j : i =< j < m : P( j ) ) • Do you see why ? A reminder

  39. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • If we have • ( A j : i =< j < k : P( j ) ) and ( A j : k =< j < m : P( j ) ) • then this is equivalent to • ( A j : i =< j < m : P( j ) ) • We simply combine the conjunctions! • Conjunction is associative: • (a and b and c) and (d and e ) = a and b and c and d and e A reminder

  40. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • We frequently have • ( A j : i =< j < k : P( j ) ) and P( k ) A reminder

  41. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • We frequently have • ( A j : i =< j < k : P( j ) ) and P( k ) • this is equivalent to • ( A j : i =< j < k + 1 : P( j ) ) • Again, we simply combine the conjunctions! A reminder

  42. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • We frequently have • ( A j : i =< j < k : P( j ) ) and P( k ) • this is equivalent to • ( A j : i =< j < k + 1 : P( j ) ) • For example, if Q( i, k ) : ( A j : i =< j < k : a[ j ] = 0 ) holds, then from • a[ k ] = 0 we can conclude that Q( i, k + 1 ) also holds. A reminder

  43. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • We frequently have • ( A j : i =< j < k : P( j ) ) and P( k ) • this is equivalent to • ( A j : i =< j < k + 1 : P( j ) ) • For example, if Q( i, k ) : ( A j : i =< j < k : a[ j ] = 0 ) holds, then from • a[ k ] = 0 we can conclude that Q( i, k + 1 ) also holds. And vice versa: if we want to • ensure that Q( i, k + 1 ) holds, we must simply perform WHAT? A reminder

  44. We want to attain a state in which some predicate R holds. • We find P, a weakening of R that looks like a good invariant, and is easier to • establish than R. • We find a boolean condition B such that P and not B implies R . • We find a way to achieve termination while keeping P invariant: this will get us to R ! • ( A j : i =< j < k : P( j ) ) • This predicate is just an abbreviation for • true and P( i ) and P( i + 1) and ... and P( k – 1 ) • We frequently have • ( A j : i =< j < k : P( j ) ) and P( k ) • this is equivalent to • ( A j : i =< j < k + 1 : P( j ) ) • For example, if Q( i, k ) : ( A j : i =< j < k : a[ j ] = 0 ) holds, then from • a[ k ] = 0 we can conclude that Q( i, k + 1 ) also holds. And vice versa: if we want to • ensure that Q( i, k + 1 ) holds, we must simply perform the assignment a[ k ] := 0 . A reminder

More Related