Computation and Deduction
Total Page:16
File Type:pdf, Size:1020Kb
Computation and Deduction Frank Pfenning Carnegie Mellon University Draft of April 2, 1997 Draft notes for a course given at Carnegie Mellon University during the fall semester of 1994. Please send comments to [email protected]. Do not cite, copy, or distribute without the express written consent of Frank Pfenning and the National Football League. Copyright c Frank Pfenning 1992–1997 ii Contents 1 Introduction 1 1.1TheTheoryofProgrammingLanguages................ 2 1.2DeductiveSystems............................ 3 1.3GoalsandApproach........................... 6 2 The Mini-ML Language 9 2.1AbstractSyntax............................. 9 2.2 Substitution . .......................... 12 2.3OperationalSemantics.......................... 13 2.4AFirstMeta-Theorem:EvaluationReturnsaValue......... 17 2.5TheTypeSystem............................. 20 2.6TypePreservation............................ 24 2.7FurtherDiscussion............................ 28 2.8Exercises................................. 31 3 Formalization in a Logical Framework 37 3.1TheSimply-TypedFragmentofLF................... 38 3.2Higher-OrderAbstractSyntax..................... 40 3.3RepresentingMini-MLExpressions................... 45 3.4JudgmentsasTypes........................... 50 3.5AddingDependentTypestotheFramework.............. 53 3.6RepresentingEvaluations........................ 56 3.7Meta-TheoryviaHigher-LevelJudgments............... 63 3.8TheFullLFTypeTheory........................ 71 3.9CanonicalFormsinLF.......................... 74 3.10SummaryandFurtherDiscussion.................... 76 3.11Exercises................................. 79 iii iv CONTENTS 4 The Elf Programming Language 81 4.1ConcreteSyntax............................. 83 4.2TypeandTermReconstruction..................... 84 4.3AMini-MLInterpreterinElf...................... 88 4.4 An Implementation of Value Soundness . ............ 97 4.5DynamicandStaticConstants..................... 101 4.6Exercises................................. 105 5 Parametric and Hypothetical Judgments 107 5.1ClosedExpressions............................ 108 5.2FunctionTypesasGoalsinElf..................... 118 5.3Negation.................................. 121 5.4RepresentingMini-MLTypingDerivations............... 123 5.5AnElfProgramforMini-MLTypeInference............. 127 5.6RepresentingtheProofofTypePreservation............. 133 5.7Exercises................................. 139 6 Compilation 145 6.1AnEnvironmentModelforEvaluation................. 146 6.2AddingDataValuesandRecursion................... 158 6.3ComputationsasTransitionSequences................. 168 6.4 Complete Induction over Computations . ............ 180 6.5AContinuationMachine......................... 181 6.6RelatingRelationsbetweenDerivations................ 192 6.7ContextualSemantics.......................... 194 6.8Exercises................................. 199 7 Natural Deduction 205 7.1NaturalDeduction............................ 206 7.2RepresentationinLF........................... 217 7.3ImplementationinElf.......................... 224 7.4TheCurry-HowardIsomorphism.................... 229 7.5GeneralizationtoFirst-OrderArithmetic............... 233 7.6 Contracting Proofs to Programs∗ .................... 239 7.7 Proof Reduction and Computation∗ .................. 241 7.8 Termination∗ ............................... 241 7.9Exercises................................. 241 8 Logic Programming 245 8.1UniformDerivations........................... 246 8.2 Canonical Forms for the Simply-Typed λ-Calculus.......... 257 8.3CanonicalFormsforNaturalDeductions................ 268 CONTENTS v 8.4CompletenessofUniformDerivations.................. 274 8.5Resolution................................. 281 8.6 Success and Failure Continuations ................... 288 9 Advanced Type Systems∗ 291 9.1 Polymorphism∗ .............................. 293 9.2 Continuations∗ .............................. 294 9.3 Intersection and Refinement Types∗ .................. 294 9.4 Dependent Types∗ ............................ 295 10 Equational Reasoning∗ 297 10.1 Cartesian Closed Categories∗ ...................... 297 10.2 A Church-Rosser Theorem∗ ....................... 297 10.3 Unification∗ ................................ 297 Bibliography 298 vi CONTENTS Chapter 1 Introduction Now, the question, What is a judgement? is no small question, because the notion of judgement is just about the first of all the notions of logic, the one that has to be explained before all the oth- ers, before even the notions of proposition and truth, for instance. —PerMartin-L¨of On the Meanings of the Logical Constants and the Justifications of the Logical Laws [ML85a] In everyday computing we deal with a variety of different languages. Some of them such as C, C++, Ada, ML, or Prolog are intended as general purpose languages. Others like Emacs Lisp, Tcl, TEX, HTML, csh, Perl, SQL, Visual Basic, VHDL, or Java were designed for specific domains or applications. We use these examples to illustrate that many more computer science researchers and system developers are engaged in language design and implementation than one might at first suspect. We all know examples where ignorance or disregard of sound language design principles has led to languages in which programs are much harder to write, debug, compose, or maintain than they should be. In order to understand the principles which guide the design of programming languages, we should be familiar with their theory. Only if we understand the properties of complete languages as opposed to the properties of individual programs, do we understand how the pieces of a language fit together to form a coherent (or not so coherent) whole. As I hope these notes demonstrate, the theory of programming languages does not require a deep and complicated mathematical apparatus, but can be carried out in a concrete, intuitive, and computational way. With a only a few exceptions, the material in these notes has been fully implemented in a meta-language, a so-called logical framework. This implementation encompasses the languages we study, the algorithms pertaining to these languages (e.g., compilation), and the proofs of their properties (e.g., compiler correctness). This allows hands-on experimentation with 1 2 CHAPTER 1. INTRODUCTION the given languages and algorithms and the exploration of variants and extensions. We now briefly sketch our approach and the organization of these notes. 1.1 The Theory of Programming Languages The theory of programming languages covers diverse aspects of languages and their implementations. Logically first are issues of concrete syntax and parsing. These have been relatively well understood for some time and are covered in numerous books. We therefore ignore them in these notes in order to concentrate on deeper aspects of languages. The next question concerns the type structure of a language. The importance of the type structure for the design and use of a language can hardly be overempha- sized. Types help to sort out meaningless programs and type checking catches many errors before a program is ever executed. Types serve as formal, machine-checked documentation for an implementation. Types also specify interfaces to modules and are therefore important to obtain and maintain consistency in large software systems. Next we have to ask about the meanings of programs in a language. The most immediate answer is given by the operational semantics which specifies the behavior of programs, usually at a relatively high level of abstraction. Thus the fundamental parts of a language specification are the syntax,thetype system,andtheoperational semantics. These lead to many meta-theoretic questions regarding a particular language. Is it effectively decidable if an input expression is well-typed? Do the type system and the operational semantics fit together? Are types needed during the execution of a program? In these notes we investigate such questions in the context of small functional and logic programming languages. Many of the same issues arise for realistic languages, and many of the same solutions still apply. The specification of an operational semantics rarely corresponds to an efficient language implementation, since it is designed primarily to be easy to reason about. Thus we also study compilation, the translation from a source language to a target language which can be executed more efficiently by an abstract machine.Ofcourse we want to show that compilation preserves the observable behavior of programs. Another important set of questions is whether programs satisfy some abstract speci- fication, for example, if a particular function really computes the integer logarithm. Similarly, we may ask if two programs compute the same function, even though they may implement different algorithms and thus may differ operationally. These questions lead to general type theory and denotational semantics, which we con- sider only superficially in these notes. We concentrate on type systems and the operational behavior of programs, since they determine programming style and are closest to the programmer’s intuition about a language. They are also amenable 1.2. DEDUCTIVE SYSTEMS 3 to immediate implementation, which is not so direct, for example, for denotational semantics. The principal novel aspect of these notes is that the operational perspective is not limited to the programming languages we study (the object language), but encompasses the meta-language, that is, the framework in which we carry out our investigation. Informally, the meta-language is centered on the notions of