Dependent Types in Practical Programming
Total Page:16
File Type:pdf, Size:1020Kb
Dependent Types in Practical Programming Hongwei Xi December 6th, 1998 Department of Mathematical Sciences Carnegie Mellon University Pittsburgh, PA 15213 Submitted in partial fulfillment of the requirements for the degree of Doctor of Philosophy Thesis Committee: Frank Pfenning, Chair Peter Andrews Robert Harper Dana Scott c 1998 Hongwei Xi This research was partially sponsored by the Defense Advanced Research Project Agency, CSTO, under the title \The Fox Project: Advanced Development of Systems Software", ARPA Order No. C533. The views and conclusions contained in this document are those of the author and should not be inter- preted as representing the official policies, either expressed or implied, of DARPA or the U.S. government. Abstract Programming is a notoriously error-prone process, and a great deal of evidence in practice has demonstrated that the use of a type system in a programming language can effectively detect program errors at compile-time. Moreover, some recent studies have indicated that the use of types can lead to significant enhancement of program performance at run-time. For the sake of practicality of type-checking, most type systems developed for general purpose programming languages tend to be simple and coarse, and this leaves ample room for improvement. As an advocate of types, this thesis addresses the issue of designing a type system for practical programming in which a notion of dependent types is available, leading to more accurate capture of program invariants with types. In contrast to developing a type theory with dependent types and then designing upon it a functional programming language, we study practical methods for extend- ing the type systems of existing programming languages with dependent types. We present an approach to enriching the type system of ML with a special form of de- pendent types, where type index objects are restricted to some constraint domains C, leading to the DML(C) language schema. The aim is to provide for specifica- tion and inference of significantly more precise type information compared with the current type system of ML, facilitating program error detection and compiler opti- mization. A major complication resulting from introducing dependent types is that pure type inference for the resulting system is no longer possible, but we show that type-checking a sufficiently annotated program in DML(C) can be reduced to con- straint satisfaction in the constraint domain C. Therefore, type-checking in DML(C) can be made practical for those constraint domains C for which efficient constraint solvers can be provided. We prove that DML(C) is a conservative extension over ML, that is, a valid ML program is always valid in DML(C). Also we exhibit the unobtrusiveness of our approach through many practical examples. As a significant application, we also demonstrate the elimination of array bound checks in real code with the use of dependent types. All the examples have been verified in a prototype implementation of a type-checker for DML(C), where C is some constraint domain in which constraints are linear inequalities on integers. This is another attempt towards refining the type systems of existing programing languages, following the step of refinement types (Freeman and Pfenning 1991). To my parents, who have been waiting patiently in general and impatiently at the last moment. Acknowledgements Foremost I especially thank my advisor Frank Pfenning for suggesting to me the wonderful thesis topic. His sharp criticism on earlier versions of type-checking algorithms for DML was inspirational to the adoption of the current bi-directional version. DML would have been much less attractive without it. I have thus learned that a program can be trusted only if it can be clearly explained. More importantly, I have also developed a taste for simplicity, which will surely have some profound influence on my future research work. I also thank him for his unusual hospitality and patience in general. I thank Peter Andrews for teaching me automated theorem proving and providing me with the opportunity to work as a research assistant on TPS, a theorem proving system based on higher- order classic logic. This really brought me a lot of first-hand experience with writing large programs in an untyped programming language (Common Lisp), and thus strongly motivated my research work. I also thank him for his kindness in general. I feel lucky that I took Robert Harper's excellent course on type theory and programming languages in 1994. I have since determined to do research related to promoting the use of types in programming. The use of dependent types in array bound check elimination was partly motivated by a question he raised during my thesis proposal. He also suggested the use of dependent types in a typed assembly language, which seems to be a highly relevant and exciting research direction to follow. I also thank him for his encouragement. I am also grateful to Dana Scott for his generous and timely help, and for his kindness in general, which I shall always look up to. Thanks to Peter Lee and George Necula for providing me with interesting examples. Thanks to Rowan Davies and Chad Brown for both helpful technical and interesting non-technical discussions. Thanks to Feng Tang for her enduring many hardships together. Also thanks to my parents for their being so patient, who once reasonably hoped that I could obtain a Ph.D degree before their retirement. Instead, they have now retired for several years. Contents 1 Introduction 1 1.1 Introductory Examples . 1 1.2 Basic Overview . 6 1.3 Related Work . 8 1.3.1 Constructive Type Theory and Related Systems . 8 1.3.2 Computational Logic PX . 9 1.3.3 The Calculus of Constructions and Related Systems . 9 1.3.4 Software Model Checking . 10 1.3.5 Extended ML . 11 1.3.6 Refinement Types . 11 1.3.7 Shape Analysis . 11 1.3.8 Sized Types . 11 1.3.9 Indexed Types . 11 1.3.10 Cayenne . 12 1.4 Research Contributions . 12 1.5 Thesis Outline . 13 2 Preliminaries 15 2.1 Untyped λ-calculus with Pattern Matching . 15 2.1.1 Dynamic Semantics . 17 2.2 Mini-ML with Pattern Matching . 19 2.2.1 Static Semantics . 20 2.2.2 Dynamic Semantics . 23 2.2.3 Soundness . 24 2.3 Operational Equivalence . 26 2.4 Summary . 32 3 Constraint Domains 35 3.1 The General Constraint Language . 35 3.2 A Constraint Domain over Algebraic Terms . 38 3.3 A Constraint Domain over Integers . 40 3.3.1 A Constraint Solver for Linear Inequalities . 40 3.3.2 An Example . 42 3.4 Summary . 43 1 2 CONTENTS 4 Universal Dependent Types 45 4.1 Universal Dependent Types . 45 4.1.1 Static Semantics . 47 4.1.2 Dynamic Semantics . 51 4.2 Elaboration . 59 Π 4.2.1 The External Language DML0(C) for ML0 (C) . 59 4.2.2 Elaboration as Static Semantics . 60 4.2.3 Elaboration as Constraint Generation . 66 4.2.4 Some Informal Explanation on Constraint Generation Rules . 72 4.2.5 An Example on Elaboration . 73 4.2.6 Elimination of Existential Variables . 77 4.3 Summary . 78 5 Existential Dependent Types 81 5.1 Existential Dependent Types . 81 5.2 Elaboration . 85 5.2.1 Coercion . 88 5.2.2 Elaboration as Static Semantics . 93 5.2.3 Elaboration as Constraint Generation . 97 5.3 Summary . 100 6 Polymorphism 103 6.1 Extending ML0 to ML08 ................................. 103 6.1.1 Static Semantics . 104 6.1.2 Dynamic Semantics . 105 Π;Σ ;Π;Σ 6.2 Extending ML0 (C) to ML08 (C) . 107 6.2.1 Static Semantics . 108 6.2.2 Dynamic Semantics . 111 6.2.3 Elaboration . 113 6.2.4 Coercion . 115 6.3 Summary . 116 7 Effects 117 7.1 Exceptions . 117 7.1.1 Static Semantics . 117 7.1.2 Dynamic Semantics . 118 7.2 References . 120 7.2.1 Static Semantics . 121 7.2.2 Dynamic Semantics . 121 7.3 Value Restriction . 125 7.4 Extending ML0;exc;ref with Polymorphism and Dependent Types . 127 7.5 Elaboration . 133 7.6 Summary . 133 CONTENTS 3 8 Implementation 135 8.1 Refinement of Built-in Types . 135 8.2 Refinement of Datatypes . 136 8.3 Type Annotations . 137 8.4 Program Transformation . 139 8.5 Indeterminacy in Elaboration . 139 8.6 Summary . 140 9 Applications 141 9.1 Program Error Detection . 141 9.2 Array Bound Check Elimination . 143 9.2.1 Experiments . 144 9.3 Potential Applications . ..