Residual Theory in λ-calculus : A Formal Development

We present the complete development, in Gallina, of the residual theory of β-reduction in pure λ-calculus. The main result is the Prism Theorem, and its corollary Lévy’s Cube Lemma, a strong form of the parallel-moves lemma, itself a key step towards the confluence theorem and its usual corollaries (Church-Rosser, uniqueness of normal forms). Gallina is the specification language of the Coq Proof Assistant[7, 11]. It is a specific concrete syntax for its abstract framework, the Calculus of Inductive Constructions[15]. It may be thought of as a smooth mixture of higher-order predicate calculus with recursive definitions, inductively defined data-types, and inductive predicate definitions reminiscent of logic programming. The development presented here was fully checked in the current distribution version Coq V5.8. We just state the lemmas in the order in which they are proved, omitting the proof justifications. The full transcript is available as a standard library in the distribution of Coq. 1 Preliminaries We shall not attempt to define formally the syntax of Gallina in this paper. First of all, we claim that this language is close enough to the standard mathematical notation that the meaning of definitions and statements ought to be obvious, once a few basic conventions are understood. For instance, the sentence (n:nat)(gt n O)+<nat>n=O corresponds to the universal quantification: ∀n ∈ IN n > O ∨ n =IN 0 It would be easy to “beautify” our mathematics, by replacing the actual Gallina code by corresponding TEX math-mode code. We have however refrained from such doctoring in this document, where the Gallina development is given verbatim. An introduction to Gallina may be found in another case study[11]. An important feature of Gallina is the definition of inductive structures and inductive predicates. To every inductive type is associated an elimination operator, corresponding to an induction principle for propositions, and a recursion principle for sets. Recursive definitions are currently handled in a primitive recursion style which is not very readable. We shall generally prefer to present these definitions first in a more usual functional programming style, à la ML. It is to be expected that future versions of Gallina will accept a more liberal and intuitive syntax. Let us now turn to the subject matter. We shall assume a certain familiarity with the elementary notions of pure λ-calculus, such as α-conversion and β-reduction, and we expect the reader to be familiar with the Tait-Martin-Löf method of proving the Church-Rosser property. The basic idea is to show the parallel-moves lemma, a diamond-like elementary paving diagram, which states that if a term M reduces to terms N and P , then N and P reduce in turn to a common term Q. Here reduction means parallel reduction of possibly several redexes, since the reduction from say M to N may duplicate some redex used in the reduction from M to P into a set of redexes, called its residuals. Furthermore, we may not restrict ourselves to parallel reduction of mutually disjoint redexes, since the residuals of disjoint redexes may not be disjoint. This is an essential difficulty of λ-calculus, which makes the proof significantly harder than say for first order rewriting of orthogonal systems. The essential notion for this proof is that of residual. One of the contributions of this paper is to propose a clear inductive definition of this notion, as a refinement of one step of parallel reduction. It is more intuitive 1This research was partially supported by ESPRIT Basic Research Action “TYPES. ” than the standard “residual map” on occurrences, and allows clear inductive proofs. One of the main new results is a Commutation Theorem, which states that residuals commute with substitution. This gives a nice algebraic structure to the inductive type representing sets of redexes, a natural enrichment of λ-terms. The parallel-moves lemma generalises on this structure as Lévy’s Cube Lemma, presented here as a corollary to a simpler diagram which we call the Prism Theorem. 2 Lambda terms We represent our λ-terms with de Bruijn’s indexes[5]. We need a minimum of arithmetical properties, concerning addition, and the standard orderings <, ≤ and > on natural numbers. Two lemmas state the decidability of those predicates: Lemma test : (n,m:nat){le n m}+{gt n m}. Lemma compare : (n,m:nat){lt n m}+{<nat>n=m}+{gt n m}. Here as everywhere in Gallina the prefix (n:nat) stands for universal quantification ∀n ∈ nat. The connective + is intuitionistic disjunction, with constructive contents. We may use the proofs of these lemmas as boolean conditionals in further definitions. Throughout this paper, we shall not provide the full formal proofs of the lemmas we state. The basic idea is that the development is sliced into small enough pieces that the logical structure of the mathematics is more or less obvious. Hints such as “this lemma is proved by induction on X” are occasionally provided. The reader interested by proof details may consult the actual transcript files in the Coq distribution. 2.1 Abstract syntax The abstract syntax of λ-terms is defined as an inductive set with three constructors, corresponding respectively to variable occurrences (represented as the reference depth from their binding abstraction), lambda abstraction and application. Inductive Set lambda = Ref : nat -> lambda | Abs : lambda -> lambda | App : lambda -> lambda -> lambda. 2.2 Lifting The first operation, an auxiliary notion necessary for substitution, is lifting, which recomputes references to global variables across n levels of extra binders in term N . The operation (lift n N) is itself defined as the base case (k = 0) of a more general (lift_rec n N k), where the operation lift_rec is defined recursively as follows: Recursive Definition lift_rec n N k = Match N with Ref(i) -> if i<k then Ref(i) else Ref(n+i) | Abs(M) -> Abs(lift_rec n M (k+1)) | App(M,N) -> App(lift_rec n M k,lift_rec n N k). Note that the argument k is just a counter of the abstraction nodes traversed during the recursion. Thus when we encounter a variable represented as a de Bruijn index Ref(i), this variable is local to the λ-term N when i < k (in which case it is untouched), and global otherwise (in which case is it relocated). The above definition of lift_rec is not accepted in Gallina’s current syntax analyser, and we must write our recursive definitions in an equivalent but more awkward primitive-recursive style as follows.