Calculi for Program Incorrectness and Arithmetic Philipp Rümmer
Total Page:16
File Type:pdf, Size:1020Kb
Thesis for the Degree of Doctor of Philosophy Calculi for Program Incorrectness and Arithmetic Philipp R¨ummer Department of Computer Science and Engineering Chalmers University of Technology and G¨oteborg University SE-412 96 G¨oteborg Sweden G¨oteborg, 2008 Calculi for Program Incorrectness and Arithmetic Philipp R¨ummer ISBN 978-91-628-7242-7 c Philipp R¨ummer, 2008 Technical Report no. 50D Department of Computer Science and Engineering Research Group: Formal Methods Department of Computer Science and Engineering Chalmers University of Technology and G¨oteborg University SE-412 96 G¨oteborg, Sweden Telephone +46 (0)31–772 1000 Printed at Chalmers, G¨oteborg, 2008 II Abstract This thesis is about the development and usage of deductive methods in two main areas: (i) the deductive dis-verification of programs, i.e., how techniques for deductive verification of programs can be used to detect program defects, and (ii) reasoning modulo integer arithmetic, i.e., how to prove the validity (and, in special cases, satisfiability) of first-order formulae that involve integer arithmetic. The areas of program verification and of testing are traditionally considered as complementary: the former searches for a formal proof of program correctness, while the latter searches for witnesses of program incorrectness. Nevertheless, de- ductive verification methods can discover bugs indirectly: the failure to prove the absence of bugs is interpreted as a sign for the incorrectness of the program. This approach is bound to produce “false positives” and bugs can be reported also for correct programs. To overcome this problem, I investigate how techniques that are normally used for verification can be used to directly prove the incorrectness of programs. This covers both the detection of partial incorrectness (a program produces results that are inconsistent with a declarative specification), and the detection of total incorrectness (a program diverges erroneously). As a prerequisite for both program correctness and incorrectness proofs, I investigate and extend the concept of updates, which is the central component for performing symbolic execution in Java dynamic logic. Updates are systematically developed as an imperative programming language that provides the following constructs: assignments, guards, sequential composition and bounded as well as unbounded parallel composition. Further, I formulate a calculus for integer arithmetic that is tailored to program verification. While restricted to ground problems, the calculus can handle both linear and nonlinear arithmetic (to some degree) and is useful both for automated and interactive reasoning. The calculus for integer arithmetic can naturally be generalised to a stand- alone procedure for Presburger arithmetic with uninterpreted predicates, which is a logic that subsumes both Presburger arithmetic and first-order logic. The procedure has similarities both with SMT-solvers and with the methods used in automated first-order theorem provers. It is complete for theorems of first-order logic, decides Presburger arithmetic, and is complete for a substantial fragment of the combination of both. IV Acknowledgements There are many people that contributed in one way or another to this thesis. First of all, I want to thank my supervisor Wolfgang Ahrendt for his advice and guidance, without which the thesis would not have been possible, and for the uncountable hours of discussions. Also my examiner Reiner H¨ahnle helped with many discussions and comments to solve problems or to recognise their true nature. I am also grateful to the further members of my advisory committee, Graham Kemp and Mary Sheeran, and to Koen Claessen for providing feedback on my work and on the thesis. It was a great experience to work with the people that coauthored articles in the thesis: the master students Muhammad Ali Shah and Helga Velroyen, as well as Wolfgang Ahrendt, Bernhard Beckert, Martin Giese, Reiner H¨ahnle, Vladimir Klebanov, Steffen Schlager, and Peter H. Schmitt. Likewise, I am thankful to all other members of the KeY project, in particular to Richard Bubel and Angela Wallenburg, for creating a fantastic group to work in. I also want to thank all PhD students and the employees at the department of Computer Science and Engineering that established such a warm and pleasant working environment, that helped me to get started in a new country, and that constantly strived to discover and get everyone into new and exciting spare time activities. Finally, I am grateful to my parents and my family for supporting me over many years and preparing me for Computing Science, and to Cigdem for always being there and helping me to stay away from Computing Science once in a while. VI Table of Contents Prologue Introduction .................................................. 1 Background .................................................. 4 1 First-Order Theorem Proving and Integer Arithmetic . 4 1.1 First-Order Logic (FOL) . ... 4 1.2 Tableaux and Sequent Calculi . 7 1.3 Reasoning about Presburger Integer Arithmetic (PA) . 12 2 Program Analysis and Deductive Program Verification . 14 2.1 Approaches to Find Bugs in Programs . 14 2.2 Semantics and Analysis of Programs . 16 2.3 Deductive Verification . 17 2.4 Testing ........................................... ....... 21 Conclusions................................................... 23 Overview of the Papers ..................................... 24 Summary of the Contributions ............................ 28 Paper 1 Proving Programs Incorrect using a Sequent Calculus for Java Dynamic Logic ................................................... ......... 39 Philipp R¨ummer, Muhammad Ali Shah 1 Introduction......................................... .......... 39 2 Formalisation of the Problem in Dynamic Logic . ..... 40 2.1 Heap Representation in Dynamic Logic for Java . 42 2.2 Formalising the Violation of Post-Conditions . 42 2.3 Quantification over Program States . 43 3 Constructing Proofs for Program Incorrectness . 44 3.1 Construction of Proofs using a Ground Procedure . 46 3.2 Construction of Proofs using Metavariables and Backtracking . 47 3.3 Construction of Proofs using Incremental Closure. 49 3.4 A Hybrid Approach: Backtracking and Incremental Closure . 50 4 Representation of Solutions: Constraint Languages . 50 5 Reasoning about Lists and Arithmetic . 51 5.1 Rules for the Theory of Lists. 52 5.2 Fairness Conditions . ..... 53 5.3 Arithmetic Handling in KeY . 54 6 RelatedWork ......................................... ........ 56 7 Conclusions and Future Work . 56 Paper 2 Non-Termination Checking for Imperative Programs ................... 61 Helga Velroyen, Philipp R¨ummer 1 Introduction......................................... .......... 61 2 Preliminaries ........................................ .......... 62 3 Proving Non-Termination: The Calculus Level . 63 Dynamic Logic for the While-Language (WhileDL). 63 Characterisation of Non-Termination. 64 A Sequent Calculus for WhileDL. 65 Incremental Closure of Proofs. 65 Example.............................................. 67 4 Automatically Detecting Non-Termination . 67 Outline of the Algorithm. 69 Invariant Creation. ................................... ..... 70 Invariant Filtering. .................................. ...... 70 Invariant Scoring. ..................................... 71 Examples............................................. 72 Properties of the Algorithm. .............................. 72 5 Experiments......................................... .......... 73 6 RelatedWork ......................................... ........ 75 7 Conclusion and Future Work . 75 Paper 3 Verifying Object-Oriented Programs with KeY: A Tutorial ............. 81 Wolfgang Ahrendt, Bernhard Beckert, Reiner H¨ahnle, Philipp R¨ummer, Peter H. Schmitt 1 Introduction......................................... .......... 81 2 TheKeYApproach........................................ ..... 82 3 Verification Case Study: A Calendar Using Interval Trees . 86 4 First Walk-through: Verifying Insertion into Interval Sequences . 88 4.1 Formal Specification and Implementation . 89 4.2 Dynamic Logic and Proof Obligations . 93 4.3 Verification........................................ ....... 98 5 Second Walk-through: Specifying and Verifying Timeframe Displays . 103 5.1 Formal Specification and Implementation . 103 5.2 Proof Obligations and Verification . 105 6 Conclusion........................................... ......... 110 VIII Paper 4 Sequential, Parallel, and Quantified Updates of First-Order Structures . 115 Philipp R¨ummer 1 Introduction......................................... .......... 115 2 Updates for Symbolic Execution in Dynamic Logic . 116 3 Syntax of Terms, Formulae, and Updates . 117 4 Semantics of Terms, Formulae, and Updates . 118 5 Application of Updates by Rewriting . 122 6 Application of Substitutions by Rewriting . 125 7 Sequentiality and Application of Updates to Updates . 125 8 Soundness and Completeness of Update Application . 127 9 Modelling Stack and Heap Structures . 128 Variables............................................ 128 LocalVariables ........................................ 128 ExplicitStack......................................... 129 Classes and Attributes . 129 ObjectAllocation ....................................... 130 Arrays ............................................. 130 10 Symbolic Execution in Dynamic Logic Revisited . 130 11 Laws for Update Simplification . 131 12 Normalisation and Equivalence Modulo Definedness . 133 Assignments vs.