Nothing Special   »   [go: up one dir, main page]

Academia.eduAcademia.edu
King’s Research Portal DOI: 10.1016/j.entcs.2016.06.008 Document Version Publisher's PDF, also known as Version of record Link to publication record in King's Research Portal Citation for published version (APA): Copello, E., Tasistro, Á., Szasz, N., Bove, A., & Fernández, M. (2016). Alpha-Structural Induction and Recursion for the Lambda Calculus in Constructive Type Theory. Electronic Notes in Theoretical Computer Science, 323, 109-124. https://doi.org/10.1016/j.entcs.2016.06.008 Citing this paper Please note that where the full-text provided on King's Research Portal is the Author Accepted Manuscript or Post-Print version this may differ from the final Published version. If citing, it is advised that you check and use the publisher's definitive version for pagination, volume/issue, and date of publication details. And where the final published version is provided on the Research Portal, if citing you are again advised to check the publisher's website for any subsequent corrections. General rights Copyright and moral rights for the publications made accessible in the Research Portal are retained by the authors and/or other copyright owners and it is a condition of accessing publications that users recognize and abide by the legal requirements associated with these rights. •Users may download and print one copy of any publication from the Research Portal for the purpose of private study or research. •You may not further distribute the material or use it for any profit-making activity or commercial gain •You may freely distribute the URL identifying the publication in the Research Portal Take down policy If you believe that this document breaches copyright please contact librarypure@kcl.ac.uk providing details, and we will remove access to the work immediately and investigate your claim. Download date: 04. Jun. 2020 Available online at www.sciencedirect.com Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 www.elsevier.com/locate/entcs Alpha-Structural Induction and Recursion for the Lambda Calculus in Constructive Type Theory Ernesto Copello 1 Álvaro Tasistro 2 Nora Szasz 3 Universidad ORT Uruguay Montevideo, Uruguay Ana Bove 4 Chalmers University of Technology Gothenburg, Sweden Maribel Fernández 5 King’s College London London, England Abstract We formulate principles of induction and recursion for a variant of lambda calculus in its original syntax (i.e., with only one sort of names) where α-conversion is based upon name swapping as in nominal abstract syntax. The principles allow to work modulo α-conversion and implement the Barendregt variable convention. We derive them all from the simple structural induction principle on concrete terms and work out applications to some fundamental meta-theoretical results, such as the substitution lemma for α-conversion and the lemma on substitution composition. The whole work is implemented in Agda. Keywords: Formal Metatheory, Lambda Calculus, Constructive Type Theory 1 Introduction We are interested in methods for formalising in constructive type theory the metatheory of the lambda-calculus. The main reason for this is that the lambda calculus is 1 2 3 4 5 Email: Email: Email: Email: Email: copello@ort.edu.uy tasistro@ort.edu.uy szasz@ort.edu.uy bove@chalmers.se Maribel.Fernandez@kcl.ac.uk http://dx.doi.org/10.1016/j.entcs.2016.06.008 1571-0661/© 2016 The Author(s). Published by Elsevier B.V. This is an open access article under the CC BY license (http://creativecommons.org/licenses/by/4.0/). 110 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 both a primigenial programming language and a prime test bed for formal reasoning on tree structures that feature (name) binding. Specifically concerning the latter, the informal procedure consists to begin with in “identifying terms up to α-conversion”. However, this is not simply carried out when functions are defined by recursion and properties proven by induction. The problem has to do with the fact that the consideration of the α-equivalence classes is actually conducted through the use of convenient representatives thereof. These are chosen by the so-called Barendregt Variable Convention (BVC): each term representing its α-class is assumed to have bound names all different and different from all names free in the current context. Now, a general validity criterion determines that this procedure ought to be accompanied in all cases by the verification that the proofs and results of functions depend only on the α-class and do not vary with the particular choice of the representative in question. Such verification is seldom accomplished but yet it is not the main difficulty concerning the validity of the constructions so performed. The crucial point is that e.g. inductive proofs are often carried out employing the structural principle for concrete terms —and then it may well happen that an induction step corresponding to functional abstractions can be carried out for a conveniently chosen bound name but not for an arbitrary one as the principle requires. The problem can be avoided by the use of de Bruijn’s nameless syntax [4] or its more up-to-date version locally nameless syntax [2,3], which uses names for the free or global variables and the indices counting up to the binding abstractor for the occurrences of local parameters. But these methods are not without overhead in the form of several operations or well-formedness predicates. As a result, there certainly is a relief in not having to consider α-conversion; but, at the same time, the nameless syntax seriously affects the connection between actual formal procedures and what could be considered the natural features of syntax. The same has to be said of the map representation introduced in [9]. A different alternative is to replace the (as explained above, problematic) use of structural induction and recursion principles on concrete terms by that of socalled alpha-structural principles working directly on the α-equivalence classes. This means providing principles that allow to prove properties by induction and to define functions by recursion by direct use of the BVC, so as to ease the burden associated to the verification of the validity of the procedure. A first attempt in this direction is [6], which gives an axiomatic description of lambda terms in which equality embodies α-conversion and that provides a method of definition of functions by recursion on such type of objects. This work ultimately rests upon the use of higher-order abstract syntax within the HOL system, and a theoretical model using de Bruijn’s nameless syntax is sketched to show the soundness of the system of axioms. In [5,12,13], models of syntax with binders are introduced which formulate the basic concepts of abstraction, α-equivalence and a name being “sufficiently fresh” in a mathematical object, on the basis of the simple operation of name swapping. This theory —which has become known as nominal abstract syntax — provides a framework of (first-order) languages with binding with associated E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 111 principles of α-structural recursion and induction that are based on the verification of the non-dependence of the mathematical objects in the current context, as well as of the results of step functions used in recursive definitions, on the bound names chosen for the representatives of the α-classes involved. Implementations of this approach have been tried in Isabelle/HOL [15] and Coq [1]. In the first case the solution rests upon a weak version of higher-order abstract syntax, whereas the second one is an axiomatisation in which —similarly to [6] cited above— equality is postulated as embodying α-conversion and a model of the system based on locally nameless syntax has been constructed. Yet another approach to the formulation of the alpha-structural principles originates in the observation that, if the property to be tried is α-compatible —i.e., it is actually a property of the α-classes and not just of the concrete terms— then (complete) induction on the size of terms can be used to bridge over the possible gap pointed out above in proofs by induction that confine themselves to convenient choice of bound names. Indeed, suppose you need to prove P(λx.M ); now, if what you have is a step from P(M ∗ ) to P(λx∗ .M ∗ ) for a convenient renaming of the term, then you will be able to use your strong size-induction hypothesis on M ∗ , since this is still of a size lesser than that of P(λx.M ). Hence you will arrive at P(λx∗ .M ∗ ) and from there to the desired P(λx.M ) because of the α-compatibility of P. This motivates trying to provide a mechanism of this kind to formalise the use of the BVC, and that is what we attempt in this paper. The result is that we are able to provide principles of alpha-structural induction and recursion, implementing the BVC in constructive type theory, using just the ordinary first-order, name-carrying syntax and actually without using the strong induction on the size of the terms —i.e. we are able to derive the principles in question from just simple structural induction on concrete terms. To such effect we define α-equivalence by using the basic concepts of nominal abstract syntax, namely freshness and swapping of names. Equality remains the simple definitional one and we do not either perform any kind of quotient construction. The whole development is implemented in the Agda system [10]. The rest of the paper goes as follows: in section 2 we present the infrastructure just mentioned. Section 3 presents the principles, starting from the simple structural induction on terms and ending up with the recursion principle on α-classes. In section 4 we show several applications that bring about certain feeling for the usefulness of the method. Finally, section 5 compares with related work and points out conclusions and further work. The present is actually a literate Agda document, where we hide some code for reasons of conciseness. The entire code is available at: https://github.com/ernius/formalmetatheory-nominal and has been compiled with the last Agda version 2.4.2.2 and 0.9 standard library. 112 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 2 Infrastructure 2.1 Agda Agda implements Constructive Type Theory [8] (type theory for short). It is actually a functional programming language in which: (i) Inductive types can be introduced as usual, i.e. by enumeration of their constructors, but they can be parameterised in objects of other types. Because of the latter it is said that type theory features families of types (indexed by a base type) or dependent types. (ii) Functions on families of types respect the dependence on the base object, which is to say that they are generally of the form (x : α) → βx where βx is the type parameterised on x of type α. Therefore the type of the output of a function depends on the value of the input. (iii) Functions on inductive types are defined by pattern-maching equations. (iv) Every function of the language must be terminating. The standard form of recursion that forces such condition is structural recursion and is, of course, syntactically checked. (v) Because of the preceding feature, type theory can be interpreted as a constructive logic. Specifically, this is achieved by representing propositions as inductive types whose constructors are the introduction rules, i.e. methods of direct proof, of the propositions in question. Therefore we can say in summary that sets of data, predicates and relations are defined inductively, i.e. by enumeration of their constructors. 2.2 Syntax The set Λ of terms is as usual. It is built up from a denumerable set of names, which we shall call atoms, borrowing terminology from nominal abstract syntax. data Λ : v _·_ ň Set where : Atom → Λ : Λ→Λ→Λ : Atom → Λ → Λ The following is called the freshness relation. It holds when a variable does not occur free in a term. Parameters to a function written between curly brackets can be omitted when invoking the function. data _#_ (a : Atom) : Λ → Set where #v : {b : Atom} → b ≡ a →a #· : {M N : Λ } →a#M→a#N →a #ň≡ : {M : Λ} →a #ň : {b : Atom}{M : Λ} → a # M →a # # # # vb M·N ňaM ňbM Next comes the fundamental operation of swapping of atoms. A finite sequence E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 113 (composition) of atom swaps constitutes a (finite) atom permutation which is the renaming mechanism to be used on terms. The action of atom swaps is first defined on atoms themselves: (_•_)A _ : Atom → Atom → Atom → Atom ? ( a • b )A c with c =A a ... | yes _ =b ? ... | no _ with c =A b ... | yes _ = a ... | no _ = c Here it extends to terms: (_•_)_ (a•b) (a•b) (a•b) : Atom → Atom → Λ → Λ vc = v (( a • b )A c) M · N = (( a • b ) M) · (( a • b ) N) ň c M = ň (( a • b )A c) (( a • b ) M) And the same goes for permutations, which are lists of swaps: _•A _ : Π → Atom → Atom π •A a = foldr (λ s b → ( proj1 s • proj2 s )A b) a π _•_ : Π → Λ → Λ π • M = foldr (λ s M → ( proj1 s • proj2 s ) M) M π We now introduce α-conversion, denoted by ∼α. We use a syntax-directed definition that uses co-finite quantification in the case of the lambda abstractions: data _∼α_ : Λ → Λ → Set where ∼αv : {a : Atom} → v a ∼α v a ∼α· : {M M’ N N’ : Λ} → M ∼α M’ → N ∼α N’ → M · N ∼α M’ · N’ ∼αň : {M N : Λ}{a b : Atom}(xs : List Atom) → ((c : Atom) → c ∈ / xs → ( a • c ) M ∼α ( b • c ) N) → ň a M ∼α ň b N The idea is that for proving two abstractions α-equivalent you should be able to prove the respective bodies α-equivalent when you rename the bound names to any name not free in both abstractions. The condition on the new name can be generalised to “any name not in a given list”, yielding an equivalent relation. The latter condition is harder to prove, but more convenient to use when you assume ∼α to hold, which is more often the case in the forthcoming proofs. 3 Alpha-Structural Induction and Recursion Principles We start with the simple structural induction over the concrete Λ terms: The next induction principle provides a strong hypothesis for the lambda ab- 114 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 TermPrimInd : {l : Level}(P : Λ → Set l) → (∀ a → P (v a)) → (∀ M N → P M → P N → P (M · N)) → (∀ M b → P M → P (ň b M)) →∀M→PM Fig. 1. Concrete Structural Induction Principle straction case: it namely allows to assume the property for all renamings (given by finite permutations of names) of the body of the abstraction: TermIndPerm : {l : Level}(P : Λ → Set l) → (∀ a → P (v a)) → (∀ M N → P M → P N → P (M · N)) → (∀ M b → (∀ π → P (π • M)) → P (ň b M)) →∀M→PM Fig. 2. Strong Permutation Induction Principle Notice that the hypothesis provided for the case of abstractions is akin to the corresponding one of the principle of strong or complete induction on the size of terms, only that expressed in terms of name permutations. This principle can be derived from the former, i.e. from simple structural induction, in very much the same way as complete induction on natural numbers is derived from ordinary mathematical induction. That is to say, we can use structural induction to prove (∀π)P (π • M ) given the hypotheses of the new principle, from which P M follows. For the interesting case of abstractions, we have to prove (∀π)P (π • ň a M ), which is equal to (∀π)P (ň (π •A a) (π • M )). The hypothesis of the new principle give us in this case (∀M  , b)((∀π  )P (π  • M  ) → P (ň b M  )). Now, instantiating M  as π • M and b as π •A a, we obtain the desired result if we know that (∀π  )P (π  • π • M ), which holds by induction hypothesis of the structural principle. We call a predicate α-compatible if it is preserved by α-conversion: αCompatiblePred : {l : Level} → (Λ → Set l) → Set l αCompatiblePred P = {M N : Λ} → M ∼α N → P M → P N For α-compatible predicates we can use the preceding principle to derive the following: TermαPrimInd : {l : Level}(P : Λ → Set l) → αCompatiblePred P → (∀ a → P (v a)) → (∀ M N → P M → P N → P (M · N)) → ∃ (λ vs → (∀ M b → b ∈ / vs → P M → P (ň b M))) →∀M→PM This new principle enables us to carry out the proof of the abstraction case by E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 115 choosing a bound name different from the names in a given list vs. It gives a way to emulate the Barendregt Variable Convention (BVC) since, indeed, the names to be avoided will always be finitely many; in using the principle we must provide a list that includes them. This same principle is provided in [1], only that we here give it a proof in terms of the ones previously introduced, instead of just postulating it. Our aim is to employ this principle whenever possible, thereby hiding the use of the swap operation which is confined to the previous principles exposed. The interesting case in the implementation of the principle is of course that of the functional abstraction. We must put ourselves in the position in which we are using the former strong principle and are given an abstraction ň b M for which we have to prove P . We have to employ to this effect the clause of our new principle corresponding to the functional abstractions, which forces us to employ a name b∗ out of the given list vs. Therefore we can aspire at proving P for a renaming of the original term, say ň b∗ M ∗ . The required result will then follow from the α-compatibility of the predicate P provided ň b∗ M ∗ ∼α ň b M . This imposes the condition that the name b∗ be chosen fresh in the original term ň b M —and that M ∗ = (b∗ • b) M . We know P M ∗ and therefore P (ň b∗ M ∗ ) because we know P for any renaming of M , by the hypothesis of the strong principle from which we start. A very important point in this implementation is that, given the list of names to be avoided, we can and do choose b∗ deterministically for each class of α-equivalent terms. Indeed, if we determine b∗ as e.g. the first name out of the given list that is fresh (i.e. not free) in the originally given term, then the result will be one and the same for every term of each α-class, since α-equivalent terms have the same free variables. Hence the representative of each α-class chosen by this method will be fixed for each list of names to be avoided, which constitutes a basis for using the method for defining functions on the α-classes. This will work by associating to (each term of) the class the result of the corresponding computation on the canonically chosen representative. More precisely, let us say that a function f : Λ → A is strongly α-compatible iff M ∼α N ⇒ f M = f N . We can now define an iteration principle over raw terms which always produces strongly α-compatible functions. For the abstraction case, this principle also allows us to give a list of variables from where the abstractions variables are not to be chosen. This iteration principle is derived from the BVC induction principle (TermαPrimInd) in a direct manner, just using a trivial constant predicate equivalent to the type A. We exhibit the type and code of the iterator: ΛIt : {l : Level}(A : Set l) → (Atom → A) → (A → A → A) → List Atom × (Atom → A → A) →Λ→A To repeat the idea, the iterator works as a function on α-classes because for each given abstraction, it will yield the result obtained by working on a canonically chosen representative that is determined by the list of names to be avoided and the 116 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 (free names of the) α-class in question. Strong compatibility would not obtain if we tried directly to formulate a recursion instead of an iteration principle, but we can recover the more general form by the standard procedure of computing pairs one of whose components is a term. Thereby we arrive at the next recursion principle over terms, which also generates strong αcompatible functions. ΛRec : {l : Level}(A : Set l) → (Atom → A) → (A → A → Λ → Λ → A) → List Atom × (Atom → A → Λ → A) →Λ→A 4 Applications in Meta-Theory We present several applications of the iteration/recursion principle defined in the preceding section. In the following two sub-sections we implement two classic examples of λ-calculus theory. In the appendix A we also apply our iteration/recursion principle to the examples of functions over terms presented in [11]. This work presents a sequence of increasing complexity functions, with the purpose of testing the applicability of recursion principles over λ-calculus terms. 4.1 Free Variables We implement the function that returns the free variables of a term. fv : Λ → List Atom fv = ΛIt (List Atom) [_] _++_ ([] , λ v r → r - v) As a direct consequence of strong α-compatibility of the iteration principle we have that α-equivalent terms have the same free variables. The relation _*_ holds when a variable occurs free in a term. data _*_ : *v : {x *·l : {x *·r : {x *ň : {x Atom → Λ → Set where : Atom} : Atom}{M N : Λ} → x * M : Atom}{M N : Λ} → x * N y : Atom}{M : Λ} → x * M → y ≡ x → → → → x x x x * * * * vx (M · N) (M · N) (ň y M) We can use our BVC-like induction principle to prove the following proposition: Pfv* : Atom → Λ → Set Pfv* a M = a ∈ fv M → a * M In the case of lambda abstractions we are able to simplify the proof by choosing the bound name different from a. This flexibility comes at a cost, i.e. we need to prove that the predicate Pfv*a is α-compatible in order to use the chosen induction principle. This α-compatibility proof is direct once we prove that * is an α-compatible E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 117 relation and the fv function is strong α-compatible. The last property is direct because we implemented fv with the iteration principle, so the extra cost is just the proof that * is α-compatible. This in turn could be directly obtained if we defined the relation establishing that a variable a is free in a term as a recursive function, as follows: _free_ : Atom → Λ → Set (_free_) a = ΛIt Set (λ b → a ≡ b) _⊎_ ([ a ] , λ _ → id) For the variable case we return the propositional equality of the searched variable to the term variable. The application case is the disjoint union of the types returned by the recursive calls. Finally, in the abstraction case we can choose the abstraction variable to be different from the searched one. In this way we can ignore the abstraction variable and return just the recursive call containing the evidence of any free ocurrence of the searched variable in the abstraction body. This implementation is strong compatible by construction because we have built it from our iterator principle, so it is also immediate from this definition that α-equivalent terms have the same free variables. 4.2 Substitution We implement capture avoiding substitution in the following way: hvar : Atom → Λ → Atom → Λ ? hvar x N y with x =A y ... | yes _ = N ... | no _ = v y – _[_:=_] : Λ → Atom → Λ → Λ M [ a := N ] = ΛIt Λ (hvar a N) _·_ (a :: fv N , ň) M It shows to be quite close to the simple pencil-and-paper version assuming the BVC. Notice that we explicitly indicate that the bound name of the canonical representative to be chosen must be different from the replaced variable and not occur free in the substituted term. Again because of the strong α-compability of the iteration principle we obtain the following result for free: lemmaSubst1 : {M N : Λ}(P : Λ)(a : Atom) → M ∼α N → M [ a := P ] ≡ N [ a := P ] lemmaSubst1 {M} {N} P a = lemmaΛItStrongαCompatible Λ (hvar a P) _·_ (a :: fv P) ň M N Using the induction principle in figure 2 we prove: lemmaSubst2 : ∀ {N} {P} M x → N ∼α P → M [ x := N ] ∼α M [ x := P ] 118 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 From the two previous results we directly obtain the α-substitution lemma: lemmaSubst : {M N P Q : Λ}(a : Atom) → M ∼α N → P ∼α Q → M [ a := P ] ∼α N [ a := Q ] lemmaSubst {M} {N} {P} {Q} a M∼N P∼Q = begin M [ a := P ] ≈ lemmaSubst1 P a M∼N N [ a := P ] ∼ lemmaSubst2 N a P∼Q N [ a := Q ]  In turn, with the preceding result we can derive that our substitution operation is α-equivalent with a naïve one for fresh enough bound names: lemmaň∼[] : ∀ {a b P} M → b ∈ / a :: fv P := →ňbM[a P ] ∼α ň b (M [ a := P ]) We can combine this last result with the TermαPrimInd principle which emulates BVC convention, and mimic in this way pencil-and-paper inductive proofs over αequivalence classes of terms about substitution operation. As an example we show next the substitution composition lemma: PSC : ∀ {x y L} N → Λ → Set PSC {x} {y} {L} N M = x ≡ y → x ∈ / fv L → (M [ x := N ]) [ y := L ] ∼α (M [ y := L ])[ x := N [ y := L ] ] We first give a direct equational proof that PSC predicate is α-compatible: αCompatiblePSC : ∀ {x y L} N → αCompatiblePred (PSC {x} {y} {L} N) αCompatiblePSC {x} {y} {L} N {M} {P} M∼P PM x≡y x∈fvL / = begin (P [ x := N ]) [ y := L ] – Strong α compability of inner substitution operation ≈ cong (λ z → z [ y := L ]) (lemmaSubst1 N x (σ M∼P)) (M [ x := N ]) [ y := L ] – We apply that we know the predicate holds for M ∼ PM x≡y x∈fvL / := (M [ y L ]) [ x := N [ y := L ] ] – Strong α compability of inner substitution operation ≈ cong (λ z → z [ x := N [ y := L ] ]) (lemmaSubst1 L y (M∼P)) (P [ y := L ]) [ x := N [ y := L ] ]  For the interesting abstraction case of the α-structural induction over the lambda term, we asume the abstraction variables in the term are not among the replaced variables or free in the subsituted terms. In this way the substitution operations E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 119 become α-compatible to naïve substitutions, and the induction hypothesis allows us to complete the inductive proof in a direct maner. The code fragment becomes: begin (ň b M [ x := N ]) [ y := L ] – Inner substitution is α equivalent – to a naive one because b ∈ / x :: fv N ≈ lemmaSubst1 L y (lemmaň∼[] M b∈x::fvN) / (ň b (M [ x := N ])) [ y := L ] – Outer substitution is α equivalent – to a naive one because b ∈ / y :: fv L ∼ lemmaň∼[] (M [ x := N ]) b∈y::fvL / ň b ((M [ x := N ]) [ y := L ]) – We can now apply our inductive hypothesis ∼ lemma∼αň (IndHip x≡y x∈fvL) / ň b ((M [ y := L ]) [ x := N [ y := L ] ]) – Outer substitution is α equivalent – to a naive one because b ∈ / x :: fv N [y := L] ∼ σ (lemmaň∼[] (M [ y := L ]) b∈x::fvN[y:=L]) / := := (ň b (M [ y L ])) [ x N [ y := L ] ] – Inner substitution is α equivalent – to a naive one because b ∈ / y :: fv L := ≈ sym (lemmaSubst1 (N [ y L ]) x (lemmaň∼[] M b∈y::fvL)) / (ň b M [ y := L ]) [ x := N [ y := L ] ]  Remarkably these results are directly derived from the first primitive induction principle, and no induction on the length of terms or accesible predicates were needed in all of this formalization. 5 Conclusions The main contribution of this work is a full implementation in Constructive Type Theory of principles of induction and recursion allowing to work on α-classes of terms of the lambda calculus. The crucial component seems to be what we called a BVC-like induction principle allowing to choose the bound name in the case of the abstractions so that it does not belong to a given list of names. This principle is, on the one hand, derived (for α-compatible predicates) from ordinary structural induction on concrete terms, thus avoiding any form of induction on the size of terms or other more complex forms of induction. And, on the other hand, it gives rise to principles of recursion that allow to define functions on α-classes, especifically, functions giving identical results for α-equivalent terms. We have also shown by way of a number of examples that the principles provide a flexible framework quite able to pleasantly mimic pencil-and-paper practice. Our work departs from e.g. [13] in that we do fix the choice of representatives for 120 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 implementing the alpha-structural recursion thereby forcing this principle to yield identical results for α-equivalent terms. This might be a little too concrete but, on the other hand, it gives us the possibility of completing a simple full implementation on an existing system, as different from other works which base themselves on postulates or more sophisticated systems of syntax or methods of implementation. We wish to continue exploring the capabilities of this method of formalisation by studying its application to the meta-theory of type systems. We also wish to deepen its comparison to the method based on Stoughton’s substitutions [14], which we started to investigate in [7] and which we believe can give rise to formulations similar to the one exposed here. References [1] Brian Aydemir, Aaron Bohannon, and Stephanie Weirich. Nominal reasoning techniques in Coq. Electron. Notes Theor. Comput. Sci., 174(5):69–77, June 2007. [2] Brian Aydemir, Arthur Charguéraud, Benjamin C. Pierce, Randy Pollack, and Stephanie Weirich. Engineering formal metatheory. In Proceedings of the 35th Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, POPL ’08, pages 3–15, New York, NY, USA, 2008. ACM. [3] Arthur Charguéraud. The locally nameless representation. J. Autom. Reasoning, 49(3):363–408, 2012. [4] N. G. de Bruijn. Lambda calculus notation with nameless dummies, a tool for automatic formula manipulation, with applications to the church-rosser theorem. Indagationes Mathematicae (Koninglijke Nederlandse Akademie van Wetenschappen), 34(5):381–392, 1972. http://www.win.tue.nl/automath/ archive/pdf/aut029.pdf Electronic Edition. [5] Murdoch J. Gabbay and Andrew M. Pitts. A New Approach to Abstract Syntax with Variable Binding. Formal Aspects of Computing, 13(3—5):341—363, July 2001. [6] Andrew D. Gordon and Thomas F. Melham. Five axioms of alpha-conversion. In Joakim von Wright, Jim Grundy, and John Harrison, editors, Theorem Proving in Higher Order Logics, 9th International Conference, TPHOLs’96, Turku, Finland, August 26-30, 1996, Proceedings, volume 1125 of Lecture Notes in Computer Science, pages 173–190. Springer, 1996. [7] Álvaro Tasistro, Ernesto Copello, and Nora Szasz. Formalisation in constructive type theory of stoughton’s substitution for the lambda calculus. Electronic Notes in Theoretical Computer Science, 312(0):215 – 230, 2015. Ninth Workshop on Logical and Semantic Frameworks, with Applications (LSFA 2014). [8] P. Martin-Löf and G. Sambin. Intuitionistic type theory. Studies in Proof Theory. Bibliopolis, 1984. [9] Helmut Schwichtenberg Masahiko Sato, Randy Pollack and Takafumi Sakurai, Viewing lambdaterms through maps, 2013, Available from http://homepages.inf.ed.ac.uk/rpollack/export/Maps_ SatoPollackSchwichtenbergSakurai.pdf [10] Ulf Norell. Towards a practical programming language based on dependent type theory. PhD thesis, Department of Computer Science and Engineering, Chalmers University of Technology, SE-412 96 Göteborg, Sweden, September 2007. [11] Michael Norrish. Recursive function definition for types with binders. In In Seventeenth International Conference on Theorem Proving in Higher Order Logics, pages 241–256, 2004. [12] Andrew M. Pitts. Nominal logic, a first order theory of names and binding. Information and Computation, 186(2):165 – 193, 2003. Theoretical Aspects of Computer Software (TACS 2001). [13] Andrew M. Pitts. Alpha-structural recursion and induction. J. ACM, 53(3):459–506, May 2006. [14] A. Stoughton. Substitution revisited. Theor. Comput. Sci., 59:317–325, 1988. [15] Christian Urban and Christine Tasson. Nominal techniques in isabelle/hol. In Robert Nieuwenhuis, editor, Automated Deduction – CADE-20, volume 3632 of Lecture Notes in Computer Science, pages 38–53. Springer Berlin Heidelberg, 2005. E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 A 121 Iteration/Recursion Applications In the following sections we successfully apply our iteration/recursion principle to all the examples from [11]. This work presents a sequence of functions whose definitions are increasing in complexity to provide a test for any principle of function definition, where each of the given functions respects the α-equivalence relation. A.1 Case Analysis and Examining Constructor Arguments The following family of functions distinguishes between constructors returning the constructor components, giving in a sense a kind of pattern-matching. isV ar : Λ → M aybe (V ariable) isApp : Λ → M aybe (Λ × Λ) isV ar (v x) = Just isApp (v x) = N othing isV ar (M · N ) = N othing isApp (M · N ) = Just(M, N ) isV ar (λxM ) = N othing isApp (λxM ) = N othing isAbs : Λ → M aybe (V ariable × Λ) isAbs (v x) = N othing isAbs (M · N ) = N othing isAbs (λxM ) = Just(x, M ) Next we present the corresponding encodings into our iteration/recursion principle: isVar : Λ → Maybe Atom isVar = ΛIt (Maybe Atom) just (λ _ _ → nothing) ([] , λ _ _ → nothing) – isApp : Λ → Maybe (Λ × Λ) isApp = ΛRec (Maybe (Λ × Λ)) (λ _ → nothing) (λ _ _ M N → just (M , N)) ([] , λ _ _ _ → nothing) – isAbs : Λ → Maybe (Atom × Λ) isAbs = ΛRec (Maybe (Atom × Λ)) (λ _ → nothing) (λ _ _ _ _ → nothing) ([] , λ a _ M → just (a , M)) 122 A.2 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 Simple recursion The size function returns a numeric measurement of the size of a term. size : Λ → N size (v x) =1 size (M · N ) = size(M ) + size(N ) + 1 size (λxM ) = size(M ) + 1 size : Λ → N size = ΛIt N (const 1) (λ n m → suc n + m) ( [] , λ _ n → suc n) A.3 Alpha Equality This function decides the α-equality relation between two terms. equal : Λ → Λ → Bool equal = ΛIt (Λ → Bool) vareq appeq ([] , abseq) where vareq : Atom → Λ → Bool vareq a M with isVar M ... | nothing = false ? ... | just b = ⌊ a =A b ⌋ appeq : (Λ → Bool) → (Λ → Bool) → Λ → Bool appeq fM fN P with isApp P ... | nothing = false ... | just (M’ , N’) = fM M’ ∧ fN N’ abseq : Atom → (Λ → Bool) → Λ → Bool abseq a fM N with isAbs N ... | nothing = false ? ... | just (b , P) = ⌊ a =A b ⌋ ∧ fM P Observe that isAbs function also normalises N, so it is correct in the last line to ask if the two bound names are the same. A.4 Recursion Mentioning a Bound Variable The enf function is true of a term if it is in η-normal form. It invokes the f v function, which returns the set of a term’s free variables and was previously defined. E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 enf : Λ → Bool enf (v x) = T rue 123 enf (M · N ) = enf (M ) ∧ enf (N ) + 1 enf (λxM ) = enf (M ) ∧ (∃N, x/isApp(M ) == Just(N, v x) ⇒ x ∈ f v(N )) _⇒_ : Bool → Bool → Bool false ⇒ b = true true ⇒ b = b – enf : Λ → Bool enf = ΛRec Bool (const true) (λ b1 b2 _ _ → b1 ∧ b2) ([] , absenf) where absenf : Atom → Bool → Λ → Bool absenf a b M with isApp M ... | nothing = b ... | just (P , Q) = b ∧ (equal Q (v a) ⇒ a ∈b (fv P)) A.5 Recursion with an Additional Parameter Given the ternary type of possible directions to follow when passing through a term (Lt, Rt, In), corresponding to the two sub-terms of an application constructor and the body of an abstraction, return the set of paths (lists of directions) to the occurrences of the given free variable in a term. Assume cons insert an element in front of a list. vposns : V ariable × Λ → List (List Direction) vposns (x, v y) = if (x == y) then [[]] else [] vposns (x, M · N ) = map (cons Lt) (vposns x M ) ++ map (cons Rt) (vposns x N ) x = y ⇒ vposns (x, λyM ) = map (cons In) (vposns x M ) Notice how the condition guard of the abstraction case is translated to the list of variables from where not to choose the abstraction variable. data Direction : Set where Lt Rt In : Direction – vposns : Atom → Λ → List (List Direction) vposns a = ΛIt (List (List Direction)) varvposns appvposns ([ a ] , absvposns) where 124 E. Copello et al. / Electronic Notes in Theoretical Computer Science 323 (2016) 109–124 varvposns : Atom → List (List Direction) ? varvposns b with a =A b ... | yes _ = [ [] ] ... | no _ = [] appvposns : List (List Direction) → List (List Direction) → List (List Direction) appvposns l r = map (_::_ Lt) l ++ map (_::_ Rt) r absvposns : Atom → List (List Direction) → List (List Direction) absvposns a r = map (_::_ In) r A.6 Recursion with Varying Parameters and Terms as Range A variant of the substitution function, which substitutes a term for a variable, but further adjusts the term being substituted by wrapping it in one application of the variable named "0" per traversed binder. sub : Λ × V ariable × Λ → Λ sub (P, x, v y) sub (P, x, M · N )  y = x ∧     ⇒ sub (P, x, λyM ) y = 0 ∧    y ∈ f v(P )  = if (x == y) then P else (v y) = (sub (P, x, M )) · (sub (P, x, N )) = λy(sub ((v 0) · M, x, M )) To implement this function with our iterator principle we must change the order of the parameters, so our iterator principle now returns a function that is waiting for the term to be substituted. In this way we manage to vary the parameter through the iteration. hvar : Atom → Atom → Λ → Λ ? hvar x y with x =A y ... | yes _ = id ... | no _ = λ _ → (v y) – sub’ : Atom → Λ → Λ → Λ sub’ x M P = ΛIt (Λ → Λ) (hvar x) (λ f g N → f N · g N) (x :: 0 :: fv P , λ a f N → ň a (f ((v 0) · N))) MP