1 Introduction
The definition of functions by recursion on the description of datatypes is the basic idea of generic programming. This method is based on defining a datatype, introduced as the universe [13], which contains datatype descriptions, such as “a list is either empty or a pair consisting of a parameter and a sublist”. Indeed, the universe constructors correspond to the common notions “either”, “pair”, “parameter” and “substructure” abstracted out of informal descriptions such as the preceding one. Then a decoding function is introduced, which interprets instances of the universe, usually called universe codes, into actual datatypes. In a dependently typed setting we can define generic functions over the universe of codes and the associated decoded datatypes. In other words, the codes provide information enough to properly traverse the structure of decoded datatype instances. Thereby, traversal becomes an operation that can be described for any recursive structure by means of generic iteration and recursion principles and, thus, code duplication is avoided by abstracting out basic operations on the datatypes. One can wonder how many other practical behaviors can undergo such kind of generalisation.
In this work we introduce a universe of regular trees [14] extended with variables (i.e. names) and binding information. We first define generic formation and elimination (i.e. induction/recursion) operators over this universe. The inclusion of names and the notion of locality allow us to introduce a generic equivalence relation, which we choose to base on nameswapping. Then we derive iteration and induction principles that capture Barendregt’s Variable Convention (BVC) which allows to proceed in proofs and definitions by conveniently choosing bound names so as to avoid conflict. At this generic level we are able to prove several properties, mainly concerning the interaction of the iteration and recursion principles with the swapping operation and equivalence relation. We next obtain calculus and System F as instances of our universe and define corresponding substitution operations as instances of the generic iteration principle. We are thereby able to derive the lemmas on compatibility of substitution with equivalence by direct instantiation of the generic properties referred to above. Finally, we prove the substitution composition lemma for the System F showing how our approach allows us to mimic the BVC, proving particular results on instances of the framework as it is usually done in penandpaper style.
1.1 Related work
Programming languages supporting native constructions to declare and manipulate abstract syntax with binders are presented by Shinwell, et. al in [18, 17], where an ML extension FreshML, and an OCaml extension Fresh O’Caml are respectively developed. These languages allow to deconstruct datatypes with binders in a safe way, that is, in the case of an abstraction inspection, a renaming with a freshly generated binder is computed for the abstraction body. In this way, the language user has access only to a fresh binder, and the renamed body of the opened abstraction. This mechanism grants that values with binders are operationally equivalent if they represent equivalent objects. This result is proved in [18] by introducing a denotational semantics of the object language FreshML into FMsets (Fraenkel and Mostowski’s sets). They prove that this denotational semantics matches the operational one. In this way, they are able to prove that values of the introduced abstract syntax with binders properly represent equivalence classes of the objectlevel syntax. In [6] Cheney carries out a similar work, but instead of developing a language extension, he implements a Haskell library called FreshLib. As the author does not implement a language from scratch, this work introduces generic programming techniques in its implementation to support the required level of genericity.
All previous works address common operations dealing with general structures with binders. Although some of these developments give proofs about the soundness of their approaches, their main concern is the implementation of metaprograms. In [11], Lee et al. use generic programming techniques to develop mechanisations of formal metatheory in the Coq proof assistant. This work allows the user to choose between nominal, locally nameless or de Bruijn firstorder syntax. For each of these representations, they offer several infrastructure operations and their associated lemmas. For instance, for the locally nameless setting, two different substitutions are needed for bound and free variables respectively. In the case of System F, where terms and type variables have binding constructions, this representation involves six different substitution operations. Hence, as the number of syntactic sorts supporting binding constructions increases in the object language, there is a combinatorial explosion of the number of operations and lemmas involved in its formalisation for the locally nameless and de Bruijn firstorder syntaxes. They manage to address these issues defining these operations and associated lemmas in a generic reusable way. Moreover, they provide a small annotation language to describe the binding structure of the object language, from which they can automatically derive an isomorphism between the object language and their generic universe syntax. However, introducing inductive relations in this framework requires the user to provide a mapping between the concrete relation, defined at the object language level, and the generic relation. They are able to instantiate some cases of the POPLmark challenge [3] in their framework, validating their approach both for the locally nameless and the de Bruijn firstorder syntax, and comparing some metrics of their approach against other solutions. However, their particular choice of universe makes it impossible to have more than one sort of binder per datatype. Hence, they cannot represent in their setting a language such as Session Types [20], where there exist three distinct sort of binders: parameters, channels and ports within a concurrent calculus. We believe their work addresses reusing and usability in great manner, but lacks in extensibility and abstraction. By using this framework it is possible to reuse several operations and lemmas that hide some of the work required by the underlying binders representation. However, in order to introduce new operations and prove results, the user may have to deal with the underlying generic abstract syntax language. Their work seems to support the nominal syntax, although no conversion relation, neither any other classic relation, property or function over named terms is presented. Indeed, they do not further develop the nominal syntax, beyond the basic definitions of a nominal abstract syntax.
In [12], Licata and Harper codify a universe that mixes binding and computation constructions in Agda, where computations are represented as metalevel functions injected in the universe constructions, i.e., they embed a HOL syntax in their development. Their representation is based on a wellscoped de Bruijn representation, that is, de Bruijn terms associated with a context indexing the free variables. For this universe, they provide a generic substitution operation, and prove context weakening and strengthening lemmas. In 2002 Pitts and Gabbay introduced the Nominal Logic [10], a firstorder manysorted logic with equality, containing primitives for renaming via nameswapping, for freshness of names, and for namebinding. The swapping operation has much nicer logical properties than the more general, nonbijective forms of renaming. This operation provides a sufficient foundation for a theory of structural induction/recursion for the syntax modulo . In [19], Urban and Tasson use ideas from Nominal Logic to construct a set of calculus terms modulo alpha, that is, identifying convertible terms. The construction is based on a HOAS syntax on top of Isabelle/HOL, deriving recursion and induction principles over this quotient set.
Our main motivation is to show it is feasible to formalise within constructive type theory iteration/ induction principles for a classical named syntax, deriving these principles from just simple structural induction on fistorder terms, where equality remains the simple definitional one, and not performing any kind of quotient on terms. Then, we want to study how feasible is to use this development in practical examples. This work is structured as follows: in Section 2 we present our regular tree universe, in Section 3 we introduce nameswapping, in Section 4 we give an conversion relation and iteration/induction schemes modulo , which allow us to define the caputreavoiding subtitution operation, and automatically derive some of its basic properties. In Section 5 we introduce the proof technique that mimics the BVC, and we apply it in the substitution composition lemma. Finally, in the last section we discuss related work and conclusions. We carry out the whole development within Constructive Type Theory as implemented in the system Agda [15]. We will show fragments of the Agda code, the complete version being available at: https://github.com/ernius/genericBindingFramework.
2 Universe of Regular Trees with Binders
2.1 Universe of (Codes of) Functors
We choose to build up a universe whose objects are codes to be interpreted as functions from Set to Set^{1}^{1}1Set is the type of (small) datatypes., i.e. as functors. The actual datatypes generated by this mechanism arise as fixed points of such functors. To this effect, we introduce in Figure 1:

the datatype Functor of codes, and

the (mutually recursiveinductive) definition of the decoding function ⟦_⟧ and of the actual datatype μ associated to any given functor code .
Notice first that the (inductive) definition of μ by means of the constructor indeed introduces it as the least fixed point of the functor corresponding to the code . Now let us examine the codes and corresponding functors. The first three constructors of datatype Functor in Figure 1 represent the embedding of: the unity type, a recursive position, and an arbitrary (i.e. externally given) datatype. The fourth constructor embeds a datatype representable in our universe, while the next two constructors represent the sum and product of types. Finally, the last two introduction rules are specific to our desired domain of abstract syntaxes with binders. As our framework supports different sorts of names, the variables and binders constructors receive as parameters an identifier of the sort of variables that they respectively introduce or bind. The binder constructor also receives the descriptor of the structure serving as scope of the bound variable. In many cases of interest (e.g. the calculus and System F to be examined shortly) this subterm descriptor will be just a recursive position. However, a compound structure is often needed, as it is the case in e.g. languages with a letrec primitive. We can observe how the variable and binder constructions inject a fixed set of variables (names) into the interpreted datatype. This set is assumed to be infinite with a decidable equality. Notice too that in the cases of the variable injection and the binder functors the sort argument has no impact on the interpreted set. Indeed, we have only one kind of names . The sort identifier will be relevant to implement generic operations related to binding issues, as shown in subsequent sections.
For example, the types of natural numbers and of lists of natural numbers can be defined as follows:
In Figure 2 we illustrate the use of the variables and binders constructions by encoding the calculus. We show the corresponding classical concrete syntax definition using comments, that are written following a dash to the right of each line. This definition has only one sort of variables identified with the sort SortλTermVars.
We next introduce notation resembling the concrete syntax of the calculus and hiding away our universe code constructions.
[GenericProgramming/Examples/LambdaCalculus.tex]lambdaconstvar
[GenericProgramming/Examples/LambdaCalculus.tex]lambdaconstapp
[GenericProgramming/Examples/LambdaCalculus.tex]lambdaconstlam
Next we present the codification of the System F. As this language also needs bindings at the type level, this encoding illustrates the use of two distinct sorts of identifiers, namely SortFTypeVars and SortλTermVars:
[GenericProgramming/Examples/SystemF.tex]systemF
[GenericProgramming/Examples/SystemF.tex]systemFmuty
[GenericProgramming/Examples/SystemF.tex]systemFmutrm
In the preceding constructions we have chosen a simplification of the universe of regular tree datatypes presented in [14], where recursive types are represented using types (from [16]). However, instead of the nominal approach traditionally used with recursive type binders, they use a wellscoped de Bruijn representation. Therefore, in order to properly interpret the full universe, a definition indexed by a context with the multiple recursive positions definitions is required. Our representation in Agda (Figure 1), simplifies this burden at the expense of not being able to represent mutually recursive datatypes. In other words, our universe construction has expressive power equivalent to admitting only a single toplevel recursive type binder.
2.2 Map and Fold
The classical definition of fold based on map that is usually introduced in category theory does not pass Agda’s termination checker. The recursive call to fold is hidden inside a call to map, and because of this the termination checker cannot determine how map is using it. To make the fold operation pass the termination checker we have to fuse map and fold into a single function, as done in [15] for a similar regular tree universe. In Figure 3 we show our implementation of the function foldmap. We make use of Agda’s implicit arguments feature, denoted by curly braces, to omit terms that the type checker can figure out for itself. For instance, we declare the set argument as an implicit argument. The presented foldmap function needs to keep two functors, since the fold (recursive) part works always over the same functor argument , while, for the map part, the auxiliary functor argument gives the position of functor during the traversal of the structure. Therefore, this function only uses the functor in the recursive case rule (the R case) in which the right hand side expression basically begins a new traversal of the functor , in a way similar to the original definition of fold. It does so by providing with a fresh copy of in the position of the auxiliary argument . The rest of the rules are equivalent to a map over the functor . Note that this definition terminates because the argument of type ⟦ G ⟧ (μ F) decreases in each recursive call. The new fold operation is defined as a recursive instance of foldmap.
As an example, we define a function vars that counts the number of variable occurrences in a term of the calculus. We do so by instantiating it as a case of the fold operation in fig. 4
Next we present a particular useful instantiation of the fold operator, named foldCtx. This instantiation aims at reproducing some techniques related to the nominal syntax considered in our work. We introduce an extra argument with type μ C, which is used by the folded function . This function is partially applied to this extra argument, and then passed as an argument of fold. Hence, this argument acts as an explicit invariant context for the function through the entire fold operation. Another difference with the original fold operation is that the result of this instance is a datatype μ H encoded in our universe instead of an arbitrary set.
[GenericProgramming/GPBindings.tex]foldCtx
From this fold instance we can directly derive the naive substitution operation for the calculus. In order to do this, we next give the functor descriptor cF for the context argument. It represents the pair formed by the variable to be replaced and the substituted term:
[GenericProgramming/Examples/LambdaCalculus.tex]substcontext
Next we define the function substaux (Figure 5) to be folded which, given a term structure with the results of the recursive calls in its recursive positions, constructs the final result of the substitution. For the variable case, we check, as usual, whether the substitution is to be applied, whereas the application and abstraction cases directly reconstruct the corresponding terms from the recursive call. Note that in the abstraction case we do not check whether the abstracted variable is different from the one being replaced, as in Barendregt’s substitution definition in [4]. In fact, this comparison would be pointless because, as we are using an iteration principle, we do not have access to the original abstraction body subterm. Note that we hide the universe codes on the right side of this definition by using the previously introduced calculus constructors.
Finally, we instantiate the foldCtx function with substaux, and its appropriate context pair to get the naive substitution operation.
[GenericProgramming/Examples/LambdaCalculus.tex]naivesubst
2.3 Primitive Induction
We now develop a more generic elimination rule than the fold operation defined above. This elimination rule captures proof by induction, and is based on the recursion rule given by Benke et al. in [5]. However, our development departs from their work in the following points: Firstly, they derive an elimination rule for a simpler universe construction, based on onesorted term algebras, and defined through signatures instead of functors. For instance, their universe does not allow the injection of previously defined datatypes, which is necessary for defining e.g. lists of natural numbers so as natural numbers become parts of the lists. Secondly, their induction principle would not pass Agda’s termination checker due to reasons similar to the ones discussed for the first version of the fold operation. To define the desired function, to be called foldInd, we first introduce the auxiliary function fih (Figure 6).
This function receives a predicate over the fixed point of a functor , and an auxiliary functor (with a similar functionality to the one used in the foldmap function). It returns a corresponding predicate of type ⟦ G ⟧ (μ F) → Set. This resulting predicate represents holding for every recursive position μ F in an element of type ⟦ G ⟧ (μ F).
We can now present our induction principle. We proceed in a similar way as we did above for the fold function. First, we introduce the foldmap fusion function foldmapFh (Figure 7). Then, we use this function to directly derive the induction principle as a recursive instance of the foldmap fusion.
We next give an example of the use of this induction principle, namely proving that the application of the function vars to any lambda term is greater than zero. We introduce the predicate Pvars representing the property to be proved and an auxiliary lemma plus>0, stating that the sum of two positive numbers is also positive.
[GenericProgramming/Examples/LambdaCalculus.tex]varsproof1
[GenericProgramming/Examples/LambdaCalculus.tex]varsproof2
The proof that Pvars holds for every term M is a direct application of the induction principle. The variable case is direct, while the application case is the application of the lemma plus>0 to the induction hypotheses. Finally, the abstraction case is a direct application of the induction hypothesis.
[GenericProgramming/Examples/LambdaCalculus.tex]proofpvars
[GenericProgramming/Examples/LambdaCalculus.tex]proof
3 NameSwapping
We now turn to considering a very basic primitive of nameswapping, which will be used for defining conversion without a mention to substitution. This constitutes the foundation of the implementation of the general idea that principles of recursion and induction ought to be defined so as to work modulo conversion, thus allowing to mimic the usual penanpaper conventions that allow the choice of convenient representatives of the terms involved in a definition or proof. The nameswapping operation completely traverses a data structure, swapping occurrences (either free, bound or binding) of two given names of some sort. Its implementation (Figure 8) is similar to that of fold.
We use an auxiliary function swapF, that takes functors and , and traverses the structure until a recursive or embedded position is reached, from where we restart the argument with either the original recursive functor or the embedded functor respectively. Note that this treatment differs from the one in the definition of fold, where this case is a base case. Here we must also traverse the embedded functor instance, as we are swapping all the variables in the structure, including the variables present in any embedded structure. Because of this, we cannot derive nameswapping as an instance of fold. In the variable and abstraction cases we use nameswapping over variables ^{2}^{2}2Requiring the decidable equality over names., denoted by the (mixfix) operator （∙）ₐ as in [8].
We prove a generic lemma about the interaction between nameswapping and the iteration principle. This lemma is presented in Figure 9, and states that the fold instance with context information is wellbehaved with respect to nameswapping, given that the respectively folded operation is also wellbehaved. Its proof goes by a direct induction on terms. This example shows how we are able to develop generic proofs over our universe with binders.
We are able to directly apply the preceding lemma to the calculus case in order to prove the result in Figure 10. This states that nameswapping commutes with substitution, which is particularly useful. We introduce the operator （∙） to denote the swapping of variables in terms. In the proof we use of the auxiliary lemma lemmasubstauxSwap which states that the function substaux, used to define substitution, is wellbehaved with respect to nameswapping. This example shows how feasible it is in our framework to instantiate generic proofs for deriving useful lemmas holding for particular instances of the generic universe.
In a similar manner we introduce a generic function returning the free variables of terms, and prove several properties about its interaction with swapping, fold, and conversion.
4 Alpha Equivalence Relation.
In Figure 11 we introduce the generic definition of the equivalence relation over our universe, named ∼α. Its definition follows a process similar to the one used before to implement generic functions over our universe. First, we define an auxiliary relation ∼αF, which is inductively defined introducing an auxiliary functor , used to traverse the functor structure. For the interesting binder case, we follow an idea similar to the one used in [8], that is, we define that two abstractions are equivalent if there exists some list of variables , such that for any given variable not in , the result of swapping the corresponding binders with in the abstraction bodies is equivalent. Note that the swapping is performed only over the sort of variables bound by this binder position, leaving any other sort of variables unchanged. We are able to prove that this is an equivalence relation, and also that it is preserved under nameswapping in a similar way as done in our previous work [8].
As we did before with nameswapping, we study how the iteration principle interacts with the introduced equivalence relation. We begin proving that the fold operation is compatible if it is applied to an also compatible function. We say a function is compatible iff it returns convertible results when it is applied to convertible arguments. In Figure 12 we state this lemma, whose proof goes by induction on terms. The only interesting case is the binders case, where we make use of the preservation of equivalence under nameswapping.
As a direct corollary we get that the fold with context instance is compatible in its context argument provided the folded function is also compatible on its arguments (Figure 13).
We define other relations over our universe in a similar way as we have done for the equivalence relation. For instance, the notOccurBind relation holds if some given variable does not occur in any binder position within a term. In this relation we discard the name sort information. We do so to simplify our next development as we will explain later. We find useful to extend this relation to lists of variables, named as ListNotOccurBind, which holds if all the variables in a given list do not occur in any binder position (associated with any sort) in a term. Using this relation we are able to prove the lemma stated in Figure 14. This lemma states that the fold with context principle is compatible on its two arguments if the provided function is compatible and wellbehaved with respect to nameswapping. Note that this lemma extends the one given before in Figure 13, although it requires extra freshness premises, and that the folded function is preserved under nameswapping.
4.1 Alpha Fold
We are now able to introduce a fold operation that works at the level of equivalence classes of terms, that is, it only defines compatible functions.
First, we introduce the function bindersFreeElem that takes a list of variables and an element , and returns an element equivalent to whose binders are not in the given list. This function will be useful to reproduce the BVC, which basically states that we can always pick a term with its binders fresh from a given context, which in this function is represented as a list of variables. We prove that this function has the important property of being strongly compatible, i.e. that it returns the same result for convertible terms.
[GenericProgramming/AlphaInduction.tex]bindersfreealphaelem
Based on this function, we next directly implement the fold principle as an instance of the fold with context function.
[GenericProgramming/AlphaInduction.tex]foldCtxalpha
This iteration principle first finds a fresh term for a given context , and then directly applies the fold operation over it. We developed this iteration principle following a different approach from the one taken in our previous work [8], where we renamed the binders during the fold traverse. Instead, we chose to separate these two stages in order to reuse the previously defined fold operation and its properties.
We can now properly justify the name “alpha” given to the introduced iteration principle. Firstly, as bindersFreeElem returns syntactical equal terms when applied to convertible terms, we have that our function is trivially strong compatible on its last term argument. Secondly, as a direct consequence from the lemma already proved for our iteration principle foldCtx in Figure 13, this new principle inherits its compatibility in its context argument from foldCtx, given that the function received is also compatible on its arguments. Thus, the presented iteration principle works at the equivalence classes level when the given function works at the same level.
Now we can derive the capture avoiding substitution operation for the lambda calculus example by a direct application of the introduced fold principle. In fact this definition is exactly the same as the one given before for the naive substitution, but using now the fold operation instead of the fold one.
[GenericProgramming/Examples/LambdaCalculus.tex]subst
Substitution lemmas stating that substitution is wellbehaved with respect to conversion are inherited from the compatibility of the iteration principle, only requiring the compatibility property of the substaux function. As this auxiliary function is not recursively defined, this proof is just a simple case analysis, while the proof involving the recursive datatype traversal is resolved at the generic level.
Next lemma in Figure 15 relates the presented fold principle with the previously defined one, giving sufficient conditions under which the two principles return convertible terms. First, the folded function must be compatible on its two arguments, and also wellbehaved with respect to nameswapping. Secondly, we need a freshness premise stating that the free variables in the context do not occur bound in the applied term.
We can instantiate this lemma to the calculus to get sufficient conditions under which the two presented substitution operations are convertible. Its proof requires two lemmas about the substaux function, one stating that it is compatible, and the other one stating that it is wellbehaved under nameswapping. Both lemmas were already used in previous proofs.
4.2 Alpha Induction Principle
In this section we generalise previous works [8, 7], developing an induction principle for compatible predicates. Our presentation introduces an explicit premise about the compatibility of the predicate being proved, which in general is not explicitly mentioned in informal developments, but is certainly required to ensure that the predicate in question is actually about abstract terms, i.e. not dependent on the choice of bound names. Hence, to prove some property over any term, this principle requires the user to prove the property only for terms with fresh enough binders, i.e. distinct from the variables in some given context, as is usually done under the BVC.
We derive this principle following a procedure similar to the one used to infer the principle in Section 2.3. We show below the interesting recursive and binder cases, the remaining ones being equivalent to those presented in Figure 6. We define an auxiliary function fihalpha, which transforms a given predicate over a datatype μ F to a predicate over the datatype ⟦ G ⟧ (μ F). This predicate states that holds for every recursive position μ F in a datatype ⟦ G ⟧ (μ F). Besides, it adds freshness premises with respect to some given variables list in the recursive and binder cases of its definition: In the binder case, it states that the binder is not in the given list , while, in the recursive case, it states that no variable in occurs in a binder position in the recursive subterm .
[GenericProgramming/AlphaInduction.tex]alphainductionhypotheses [GenericProgramming/AlphaInduction.tex]alphainductionhypothesescases
We state this principle in Figure 16. Its proof is similar to the fold principle’s proof. We firstly use the function bindersFreeElem (from Section 4.1) over the parameter and the freshness context to get an equivalent term with binders not occurring in the list . Then we apply the primitive induction principle (Figure 7) over the fresh term to prove the following predicate :
Finally, we apply the proof of predicate to the term and its freshness hypothesis to obtain that must hold. Hence, as the predicate is compatible, and , we get that should also hold.
The proof of is done using an auxiliary lemma which recursively reconstructs a proof of fihalpha given that fih holds and that the binders of do not occur in the context . This proof is just a generalisation of the one already presented in [7] for an equivalent induction principle for calculus. In this previous work we were also able to prove the ChurchRosser theorem for the calculus using this equivalent induction principle. Therefore, we conjecture that following the same procedure we would be able to achieve the confluence of reduction result within our generic framework. However, we sketch another approach in next section to prove the substitution composition lemma, a crucial lemma in the confluence proof.
5 Codification of a BVC proof technique.
In Figure. 17 we show a result that validates the BVC and usual practices in common penandpaper proofs within our generic framework. It states that for any compatible predicate , we can prove for any term by just proving it for terms whose binders are all different from their own free variables and from the variables in an arbitrary list . As in previous induction principle, this technique requires the compatibility of the predicate being proved.
To prove for arbitrary , we proceed as follows: We first find a fresh enough term such that using the function bindersFreeElem. Then, we can use the hypothesis for the fresh term to derive that holds. Finally, must also hold, as is compatible. We do not show the code of the proof, since it is similar to others previously presented.
Next we illustrate the use of this result to prove the substitution composition lemma for System F. First, we prove this lemma for the naive substitution operation. Next we introduce the property to be proved. Note that an extra freshness premise stating that does not occur bound in the term is required, since we use the naive substitution.
[GenericProgramming/Examples/SystemF.tex]substnaivecompositionpredicate
The proof is done using the structural induction principle (Figure 7). We show below the interesting abstraction case:
[GenericProgramming/Examples/SystemF.tex]substncompositionabstractioncase
This equational proof is constructed following the usual penandpaper practice: First we push the substitution inside the abstraction. Then, by the induction hypothesis we know that the composition of substitutions in the abstraction bodies are convertible, and hence we are able to prove that the entire abstraction is convertible too, using the auxiliary lemma lemma∼+B. Finally, we push back the substitutions outside the abstraction to conclude the proof.
Now we prove the substitution composition lemma for the captureavoiding substitution operation using the introduced proof technique. We begin by defining the functor describing a triple of terms TreeTermF. Then, we introduce the predicate PSComp over triples, stating the composition lemma for the substitution.
[GenericProgramming/Examples/SystemF.tex]substcompositionpredicate
We prove that PSComp is compatible with respect to triples of terms by a direct equational proof using basically the previous substitution lemmas. In Figure 18 we show the core of the proof. It uses the preceding substitution lemmas to replace the classical substitution operations with the naive ones. This can be done because we have freshness premises stating that in the introduced context of triples all binders are different from the free variables in the involved terms, and also from variables and . Finally, we work in very much the same way as we did at the beginning to recover the classical substitutions from the naive ones. There are many auxiliary lemmas and boilerplate code concerning the freshness premises involved in the last proof which we do not show in this presentation. These are hidden inside auxiliary lemmas as: y:fvLNBM[x≔N]ₙ and y:fvLNBN occurring in the proof. The first of these lemmas, for instance, proves that neither the variable nor the free variable binding in occur bound in , which is easy to verify from the freshness premises. However, we believe further work is necessary to automatise some of these proofs, or even rewriting the freshness relations in order to alleviate its handling.
Finally, we can use the introduced proof principle with the previous proof obligations to finish the proof. Note how, by applying the proof technique to a triple of terms, we were able to get sufficient freshness premises to develop a proof similar in structure to penandpaper ones in a direct manner. This is possible because in our generic framework we can state the equivalence of any structure (triples in this case), and not just language terms.
6 Conclusions
We address the formalisation of a general first order named syntax with multisorted binders by applying a combination of generic programming and nominal techniques to derive fold operations, nameswapping, the conversion relation, and induction/iteration principles for any language abstract syntax with binders. We derive the calculus and System F as instances of the introduced general framework. For these examples we derive both the naive and the captureavoiding substitutions as direct instances of the corresponding fold and fold principles. We directly inherit the classical substitution lemmas for the conversion, and the good behavior of substitution under the nameswapping from fold properties already proved at the generic level. We prove a lemma stating sufficient conditions under which the fold and fold functions are equivalent. Therefore, as substitution operations are direct instances of these iteration principles, we get in an almost free manner a result about the relation between the naive and the captureavoiding substitution operations for the calculus and System F. This result is particularly useful in the last proof, which is conducted using the introduced proof technique, that enables us to mimic the BVC in a generic setup.
Our work uses generic programming techniques to develop the metatheory of abstract syntax with binders in a general way as in related works. But we choose to maintain names for binders like as usually done in informal practice. On the other hand, contrary to the historical standpoint, following ideas in [10], we give conversion a more fundamental role than that of the definition of substitution. Indeed, we verify that the nameswapping is powerful enough to define a theory of structural induction/recursion modulo in a general way.
We generalise the recursion/induction principles developed in [8, 7]. In these previous works we renamed binders within the fold traversal. Instead, in this work we separate these stages, managing to reuse the fold operation and its properties. We also present an proof technique which is not based on an induction principle as in the previous works, and thus can be used to prove properties over relations or composite datatypes. This is the case in the proof of the substitution composition lemma, where it is used to obtain freshness premises over a triple of terms, which is possible because of the generic character of the approach, allowing us to state the equivalence or freshness premises over any composite datatype; that is, we are able to state freshness in any mathematical context, thus reflecting the BVC more accurately.
Generic programming techniques are capable of further improvements as the one considered in [9], where a more modular assembly is introduced, enabling a more structured approach to the reuse of metatheory formalisations through the composition of modular inductive definitions and proofs. The present work does not directly support a modular reuse, but it would be interesting to explore this improvement.
In [2] Reynold’s parametricity theory is used to prove the compatibility property of a big step semantics using reflection within Coq. They introduce a lambda calculus terms interface, and by a formalisation of Reynold’s parametricity, they prove that polymorphic functions (over this interface) applied to related inputs produces related outputs. Then, given two concrete implementations of their lambda terms interface, one with de Brujin syntax (where αconvertible are syntaticaly equal), and another one nominal, they are able to get as a "free theorem" that on αconvertible inputs, the big step function produces αconvertible outputs in the nominal syntax. It remains as future work to study how our generic framework could be used to internalise this kind of "free theorems" by introducing a de Brujin interpretation to our universe, and then translate results between interpretations.
Acknowledgements. We gratefully acknowledge DoD support under award FA95501610082 (MURI Program).
References
 [1]
 [2] Abhishek Anand & Greg Morrisett (2017): Revisiting Parametricity: Inductives and Uniformity of Propositions. CoRR abs/1705.01163. Available at http://arxiv.org/abs/1705.01163.
 [3] B. Aydemir, A. Bohannon, M. Fairbairn, N. Foster, B. Pierce, P. Sewell, D. Vytiniotis, G. Washburn, S. Weirich & S. Zdancewic (2005): Mechanized Metatheory for the Masses: The PoplMark Challenge. In: Proceedings of TPHOLs’05, SpringerVerlag, pp. 50–65, doi:http://dx.doi.org/10.1007/11541868_4.
 [4] Hendrik Barendregt (1984): The calculus Its Syntax and Semantics, revised edition. Studies in Logic and the Foundations of Mathematics 103, North Holland, doi:http://dx.doi.org/10.2307/2274112.
 [5] Marcin Benke, Peter Dybjer & Patrik Jansson (2003): Universes for Generic Programs and Proofs in Dependent Type Theory. Nordic Journal of Computing 10(4), pp. 265–289. Available at http://dl.acm.org/citation.cfm?id=985799.985801.
 [6] James Cheney (2005): Scrap Your Nameplate: (Functional Pearl). In: Proceedings of the Tenth ACM SIGPLAN International Conference on Functional Programming, ICFP ’05, ACM, New York, NY, USA, pp. 180–191, doi:http://dx.doi.org/10.1145/1086365.1086389.
 [7] Ernesto Copello, Nora Szasz & Álvaro Tasistro (2017 in press): Machinechecked proof of the ChurchRosser Theorem for the Lambda Calculus using the Barendregt Variable Convention in Constructive Type Theory. In: LSFA 2017. Available at http://lsfa2017.cic.unb.br/LSFA2017.pdf.
 [8] Ernesto Copello, Álvaro Tasistro, Nora Szasz, Ana Bove & Maribel Fernández (2016): AlphaStructural Induction and Recursion for the calculus in Constructive Type Theory. ENTCS 323, pp. 109 – 124, doi:http://dx.doi.org/10.1016/j.entcs.2016.06.008.
 [9] Benjamin Delaware, Bruno C. d. S. Oliveira & Tom Schrijvers (2013): Metatheory à La Carte. SIGPLAN Not. 48(1), pp. 207–218, doi:http://dx.doi.org/10.1145/2429069.2429094.
 [10] Murdoch J. Gabbay & Andrew M. Pitts (2001): A New Approach to Abstract Syntax with Variable Binding. Formal Aspects of Computing 13(3—5), p. 341—363, doi:http://dx.doi.org/10.1007/s001650200016.
 [11] Gyesik Lee, Bruno Oliveira, Sungkeun Cho & Kwangkeun Yi (2012): GMeta: A Generic Formal Metatheory Framework for FirstOrder Representations. Springer, doi:http://dx.doi.org/10.1.1.298.2957.
 [12] Daniel R. Licata & Robert Harper (2009): A universe of binding and computation. In: International Conference on Functional Programming (ICFP), pp. 123–134, doi:http://dx.doi.org/10.1145/1596550.1596571.
 [13] Per MartinLöf (1984): Intuitionistic type theory. Studies in Proof Theory. Lecture Notes 1, Naples.
 [14] Peter Morris, Thorsten Altenkirch & Conor McBride (2006): Exploring the Regular Tree Types. In: International Conference on Types for Proofs and Programs, TYPES’04, SpringerVerlag, Berlin, Heidelberg, doi:http://dx.doi.org/10.1007/11617990_16.
 [15] Ulf Norell (2009): Dependently Typed Programming in Agda. In: Proceedings of the 6th International Conference on Advanced Functional Programming, AFP’08, SpringerVerlag, Berlin, doi:http://dx.doi.org/10.1145/1481861.1481862.
 [16] Benjamin C. Pierce (2002): Types and Programming Languages, 1st edition. The MIT Press.
 [17] Mark R. Shinwell (2006): Fresh O’Caml: Nominal Abstract Syntax for the Masses. ENTCS 148(2), doi:http://dx.doi.org/10.1016/j.entcs.2005.11.040.
 [18] Mark R. Shinwell, Andrew M. Pitts & Murdoch James Gabbay (2003): FreshML: programming with binders made simple. SIGPLAN Notices 38(9), pp. 263–274, doi:http://dx.doi.org/10.1145/944746.944729.
 [19] Christian Urban & Christine Tasson (2005): Nominal Techniques in Isabelle/HOL. In: Automated Deduction – CADE20, LNCS 3632, Springer Berlin Heidelberg, doi:http://dx.doi.org/10.1007/s1081700890972.
 [20] Nobuko Yoshida & Vasco T. Vasconcelos (2007): Language Primitives and Type Discipline for Structured CommunicationBased Programming Revisited: Two Systems for HigherOrder Session Communication. ENTCS 171(4), pp. 73 – 93, doi:http://dx.doi.org/10.1016/j.entcs.2007.02.056.
Comments
There are no comments yet.