\documentclass[prodtf]{jfp1} \usepackage[french,english]{babel} \usepackage{amssymb} \usepackage{stmaryrd} \usepackage[T3,OT1]{fontenc} \def\mynegthinspace{\!} \DeclareRobustCommand{\dedicace}[1]{% \cleardoublepage \thispagestyle{empty} \vspace*{\stretch{1}}\par {\begin{flushright}\emph{#1}\end{flushright}\par} \vspace*{\stretch{2}} } \DeclareTextSymbol\nptextcrlambda{T3}{172} \DeclareTextSymbolDefault\nptextcrlambda{T3} \DeclareFontFamily{U}{matha}{\hyphenchar\font45} \DeclareFontShape{U}{matha}{m}{n}{ <5> <6> <7> <8> <9> <10> gen * matha <10.95> matha10 <12> <14.4> <17.28> <20.74> <24.88> matha12 }{} \DeclareSymbolFont{matha}{U}{matha}{m}{n} \DeclareFontSubstitution{U}{matha}{m}{n} \DeclareFontFamily{U}{npmathb}{\hyphenchar\font45} \DeclareFontShape{U}{npmathb}{m}{n}{ <5> <6> <7> <8> <9> <10> gen * mathb <10.95> mathb10 <12> <14.4> <17.28> <20.74> <24.88> mathb12 }{} \DeclareSymbolFont{npmathb}{U}{npmathb}{m}{n} \DeclareFontSubstitution{U}{npmathb}{m}{n} \DeclareMathSymbol{\npoasterisk} {2}{matha}{"66} % to fool the highlighter => " \DeclareMathSymbol{\npnotequiv} {3}{matha}{"19} % to fool the highlighter => " \DeclareMathSymbol{\npdotdiv} {2}{npmathb}{"01} % to fool the highlighter => " \usepackage{url} \usepackage{makeidx} \usepackage[pdftex,bookmarks=true,bookmarksopen=true,colorlinks=false,linkcolor=false,citecolor=false,urlcolor=false,hidelinks=true]{hyperref} \usepackage{tikz} \makeindex \usetikzlibrary{arrows,positioning} \title{A unified treatment of syntax with binders} \author[N. Pouillard and F. Pottier] {Nicolas POUILLARD and Fran\c{c}ois POTTIER\\ INRIA\\ \email{np@nicolaspouillard.fr and francois.pottier@inria.fr}} \jdate{TODO} \pagerange{TODO--TODO} \pubyear{2012} \volume{TODO} \doi{TODO} \begin{document} \maketitle \begin{abstract} Atoms and de Bruijn indices are two well-known representation techniques for data structures that involve names and binders. However, using either technique, it is all too easy to make a programming error that causes one name to be used where another was intended. We propose an abstract interface to names and binders that rules out many of these errors. This interface is implemented as a library in Agda. It allows defining and manipulating term representations in nominal style and in de Bruijn style. The programmer is not forced to choose between these styles: on the contrary, the library allows using both styles in the same program, if desired. Whereas indexing the types of names and terms with a natural number is a well-known technique to better control the use of de Bruijn indices, we index types with worlds. Worlds are at the same time more precise and more abstract than natural numbers. Via logical relations and parametricity, we are able to demonstrate in what sense our library is safe, and to obtain theorems for free about world-polymorphic functions. For instance, we prove that a world-polymorphic term transformation function must commute with any renaming of the free variables. The proof is entirely carried out in Agda. \end{abstract} \section{Introduction} % %paragraphName: representations with names and binders in the wild Many programmers have to deal with the mundane business of building and transforming data structures that contain names and binders. Compilers, code generators, static analysers, theorem provers, and type-checkers have this in common. They manipulate programs, formulae, proofs, and types. One central difficulty is the representation of variables, that is, the representation of names and binders.% % %paragraphName: named One traditional approach is to represent all occurrences of a variable identically. For this purpose, one typically uses character strings or integers. One can in fact use any data type that has an infinite number of elements and admits an equality test. The nature of its elements does not matter, which is why they are often known as \emph{atoms}. While this seems to be the most obvious representation, it causes trouble when dealing with operations like substitution. Substitution must be capture-avoiding{:} variables must sometimes be renamed in order to avoid an accidental change of meaning of a name. The mathematical foundations of this technique, which we refer to as the \emph{nominal} approach, are described by Pitts{~}\shortcite{pitts-06}.% % %paragraphName: nameless Another traditional approach is to use de Bruijn indices{~}\cite{de-bruijn-72}. This representation is often referred to as {``}nameless{''} because variables are no longer identified by a name but by a notion of {``}distance{''} to the binding point. This approach solves part of the problem by providing a canonical representation. However, due to its arithmetic flavor, the manipulation of de Bruijn indices remains an error-prone activity.% % %paragraphName: hard In the end, regardless of which representation is used, programs that work with names can be hard to understand and are easy to get wrong. To remedy this, many proposals have been made, often in the form of finer-grained type systems for these representations{~}\cite{altenkirch-93,mcbride-mckinna-04,bellegarde-94,bird-paterson-99,altenkirch-reus-99,shinwell-03,licata-harper-09,pottier-lics-07}. We continue in this direction by presenting a library whose abstract types allow safe and fine-grained programming with both named and nameless representations.% % %paragraphName: brief connection with our previous papers This paper combines the conference papers by Pouillard and Pottier{~}\shortcite{pouillard-pottier-10} and by Pouillard{~}\shortcite{pouillard-11} and extends them significantly. In the first conference paper, we present an abstract interface to names and binders. This interface comes with \emph{two} implementations, one of which is in nominal style, the other in de Bruijn style. Thus, client code can be written and type-checked independently of which representation technique is ultimately chosen. In the second conference paper, Pouillard drops the nominal implementation and focuses on the de Bruijn side. Furthermore, he exploits dependent types, whereas the first conference paper avoids them. These decisions allow him to greatly simplify the interface of the library, which now has just one implementation. In the present paper, we stick with a single interface and \emph{a single implementation}, but we extend them in such a way that \emph{the nominal representation and de Bruijn{'}s representation} (as well as several others) \emph{are simultaneously available} to the client.% % %paragraphName: connection summary The connection with our previous papers is described in greater depth in section{~}\ref{relatedS}. Here, let us just stress again our main contribution{:} whereas the first conference paper {``}unifies{''} the nominal representation and de Bruijn{'}s representation by supporting one \emph{or} the other, the present paper {``}unifies{''} them by supporting them \emph{simultaneously}.% % %paragraphName: plan This paper is organized as follows. In section{~}\ref{agdaS}, we briefly recall a few facts about \textsc{Agda}, the language in which we write both our programs and proofs about these programs. Then, we begin the presentation of our library. We decide to initially focus on the fragment of the library that supports programming in nominal style (sections{~}\ref{introNominal} to{~}\ref{nompaSoundnessS}). We informally recall several existing approaches to representing data structures with names and binders in a nominal style (section{~}\ref{introNominal}). Then, we explain our new approach, by presenting the interface of (the nominal fragment of) our library (section{~}\ref{nompaIface}), its usage (section{~}\ref{usingNompa}), and its implementation (section{~}\ref{nompaImplem}). In section{~}\ref{nompaSoundnessS}, we use logical relations and parametricity in order to explain and prove in what sense our library is safe. At this point, we are ready to extend the library with support for de Bruijn indices. We follow an analogous path as in the nominal case. First, we informally recall several existing approaches to working with de Bruijn indices in a {``}safe{''} manner. Then, we extend the interface and implementation of our library (section{~}\ref{napaS}). We explain how these extensions can be exploited by the library{'}s users (section{~}\ref{usingNaPa}) and why they are sound (section{~}\ref{napaRel}). Let us stress again that this is not an alternative implementation of the library, but an extension of it. Finally, we review some of the related work (section{~}\ref{relatedS}) and discuss several directions for future work (section{~}\ref{conclusionS}).% \section{A brief introduction to \textsc{Agda}\label{agdaS}} % %paragraphName: intro Throughout the paper, our definitions are presented in the syntax of \textsc{Agda}. Naturally, we cannot possibly provide a self-contained introduction to \textsc{Agda} in this paper. In the following, we present a few of \textsc{Agda}{'}s notations and conventions. We hope that this is enough for someone who is familiar with functional programming to understand our code.% % %paragraphName: Agda reference To better grasp the features of \textsc{Agda}, we recommend the following further reading. Norell{'}s Ph.D. thesis \shortcite{norell-07} describes the theoretical and practical aspects of the development of \textsc{Agda}. Another introduction to \textsc{Agda}, of intermediate size, can be found in the introduction of Pouillard{'}s Ph.D. thesis{~}\shortcite{pouillard-12}.% \paragraph{Types} % %paragraphName: type theory \textsc{Agda} is a dependent type theory. This means, in particular, that it has very few built-in types. In fact, only two forms of types are built-in, namely function types and the type of all types. Everything else is a user-defined type. The language offers facilities for defining record types, inductive types, and co-inductive types.% % %paragraphName: → An ordinary (non-dependent) function type is written{~}\texttt{A\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B}. A dependent function type is written{~}\texttt{\makebox[1.22ex][l]{$ {(} $}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{B\makebox[1.22ex][c]{{~}}} or{~}\texttt{\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B}. A function parameter can be implicit{:} in this case, the function type is written{~}\texttt{\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B}. This allows an actual parameter to be omitted at a call site if its value can be inferred from the context. The distinction between{~}\texttt{\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B} and{~}\texttt{\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B} is quite superficial{:} in principle, after reconstructing the value of every omitted actual parameter, one can put every program in a form where every function parameter is explicit. This means, in particular, that the logical relations (and the {``}free theorems{''}) associated with the types{~}\texttt{\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B} and{~}\texttt{\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B} are the same.% % %paragraphName: →shortcuts The syntax of function types offers shortcuts for introducing multiple arguments at once and for omitting a type annotation, as in{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}A\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}i\makebox[1.22ex][c]{{~}}j\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}C}.% % %paragraphName: Set The type \texttt{Set}\index{Keyword!\texttt{Set}}, also known as{~}\texttt{Set\makebox[0.61ex][l]{$ _{{0}} $}}\index{Code!\texttt{Set\makebox[0.61ex][l]{$ _{{0}} $}}}, is the type of all {``}small{''} types, such as \texttt{List\makebox[1.22ex][c]{{~}}String}, \texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}}, and \texttt{Maybe\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}Bool\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \times $}\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][r]{$ {)} $}}. The type \texttt{Set\makebox[0.61ex][l]{$ _{{1}} $}}\index{Code!\texttt{Set\makebox[0.61ex][l]{$ _{{1}} $}}} is the type of{~}\texttt{Set} and {``}others like it{''}, such as \texttt{Set\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Bool}, \texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Set}, and{~}\texttt{Set\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Set}. There is in fact an infinite hierarchy of types of the form{~}\texttt{Set\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}, where{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} is a universe level, roughly, a natural integer.% \paragraph{Propositions} % %paragraphName: no prop There is no specific sort of propositions{:} instead, propositions inhabit{~}\texttt{Set\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} for some{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}. The unit type{~}\texttt{\makebox[1.22ex][c]{$ \top $}}\index{Code!\texttt{\makebox[1.22ex][c]{$ \top $}}}, a record type with no fields, represents the true proposition. The empty type{~}\texttt{\makebox[1.22ex][c]{$ \bot $}}\index{Code!\texttt{\makebox[1.22ex][c]{$ \bot $}}}, an inductive type with no constructors, represents the false proposition. Negation{~}\texttt{\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][c]{{~}}A}\index{Code!\texttt{\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][c]{{~}}A}} is defined as{~}\texttt{A\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \bot $}}.% \paragraph{Lexical conventions} % %paragraphName: agda lexical syntax Whitespace is significant{:} \texttt{x\makebox[1.22ex][c]{$ \leq $}y} is an identifier, whereas{~}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \leq $}\makebox[1.22ex][c]{{~}}y} is an application. This makes it possible to name a variable after its type, deprived of any whitespace. For example, if one follows this convention, then a variable of type{~}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \leq $}\makebox[1.22ex][c]{{~}}y} (that is, a proof of{~}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \leq $}\makebox[1.22ex][c]{{~}}y}) is named{~}\texttt{x\makebox[1.22ex][c]{$ \leq $}y}.% % %paragraphName: mixfix \textsc{Agda} offers infix and {``}mixfix{''} notation. For instance, the expression{~}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \leq $}\makebox[1.22ex][c]{{~}}y} is syntactic sugar for an application of the function{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \leq $}\makebox[1.22ex][c]{\_{}}} to the arguments{~}\texttt{x} and{~}\texttt{y}. Note how, in the name of the function, the underscore character {``}\_{}{''} is used to indicate where the arguments should appear.% % %paragraphName: agda constructors Note that the same name can be used for different data constructors of distinct data types. \textsc{Agda} makes use of type annotations to resolve ambiguities.% % %paragraphName: holes \textsc{Agda} programs can be constructed incrementally. To do so, one makes use of {``}holes{''}, which represent the unfinished parts of a program. Whatever appears inside a hole is not type-checked. The hole itself can receive any type. A hole is delimited by curly braces and exclamation marks,{~}\texttt{\makebox[1.22ex][l]{\{{}}!like\makebox[1.22ex][c]{{~}}this!\makebox[1.22ex][r]{\}{}}}. In the following, we use holes when we want to omit a definition or a proof.% % %paragraphName: Comments A comment begins with{~}\texttt{--} and extends to the end of the line.% \paragraph{Notions of equality} % %paragraphName: definitional equality In type theory, there are several notions of equality. \emph{Definitional equality}\index{Definitional equality} is the most basic notion. It is deeply rooted in the computation rules of the programming language, here, \textsc{Agda}. Two terms are \emph{definitionally equal}\index{definitionally equal} if and only if they reduce to a common term. In \textsc{Agda}, reduction combines $ \beta $-reduction, $ \eta $-conversion, and expansion of the equations that appear as part of definitions.% % %paragraphName: examples For instance, \texttt{\makebox[1.22ex][l]{$ {(} $}$ \lambda $\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}suc\makebox[1.22ex][c]{{~}}zero} is definitionally equal to \texttt{suc\makebox[1.22ex][c]{{~}}zero}, and{~}\texttt{suc} is definitionally equal to{~}\texttt{$ \lambda $\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{suc\makebox[1.22ex][c]{{~}}x}. The term{~}\texttt{zero\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}n} is definitionally equal to{~}\texttt{n}, because the definition of addition is by case analysis upon its first argument. For the same reason, \texttt{n\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}zero} is not definitionally equal to{~}\texttt{n}.% % %paragraphName: propositional equality Definitional equality is decidable but weak. When one wishes for a notion of equality that relies not just on computation, but also on reasoning, one turns to \emph{propositional equality}\index{propositional equality}. In \textsc{Agda} and in this document, this equality is written{~}\texttt{$ \equiv $}\index{Code!\texttt{$ \equiv $}}. Its negation is written{~}\texttt{\ensuremath{\npnotequiv}}\index{Code!\texttt{\ensuremath{\npnotequiv}}}. Propositional equality is defined as an inductive type, in the following style{:}% {\nopagebreak } % %code: % %comment: data _≡₀_ {A : Set₀} (x : A) : A → Set₀ where % refl : x ≡₀ x % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}refl\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: comments on the definition For simplicity, the above definition defines{~}\texttt{\makebox[1.22ex][c]{\_{}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\_{}}}}, a version of propositional equality that is restricted to {``}small{''} types of type{~}\texttt{Set\makebox[0.61ex][l]{$ _{{0}} $}}. We cannot fully explain the subtleties of this definition. Let us only point out that this inductive type has a single constructor, which requires both sides of the equality to be the same, that is, to be definitionally equal.% % %paragraphName: examples Propositional equality subsumes definitional equality. For example, the proposition \texttt{zero\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}n\makebox[1.22ex][c]{{~}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{{~}}n} is true, because the terms{~}\texttt{zero\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}n} and{~}\texttt{n} are definitionally equal and (as a result) the term{~}\texttt{refl} is an inhabitant of the type{~}\texttt{zero\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}n\makebox[1.22ex][c]{{~}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{{~}}n}. Propositional equality is strictly more powerful than definitional equality. For instance, the proposition \texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}n\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}n\makebox[1.22ex][c]{{~}}+}{ }\texttt{zero\makebox[1.22ex][c]{{~}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{{~}}n} can be proved by a simple induction on{~}\texttt{n}.% % %paragraphName: pointwise equality Although propositional equality is stronger than definitional equality, it is still an \emph{intensional} notion of equality. It is sometimes the case that it cannot relate two functions even though they are \emph{pointwise equal}\index{pointwise equal}, that is, they map every input to the same output. Thus, it makes sense to introduce an \emph{extensional} notion of equality, namely pointwise equality, written{~}\texttt{\ensuremath{\circeq}}\index{Code!\texttt{\ensuremath{\circeq}}}. The definition presented here is specialized to small types, non-dependent functions, and the equality remains \emph{intensional} on the codomain of the functions{:}% {\nopagebreak } % %code: % %comment: _≗₀_ : {A B : Set₀} (f g : A → B) → Set₀ %f ≗₀ g = ∀ x → f x ≡₀ g x % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\ensuremath{\circeq}\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}{\nopagebreak \newline% }\vphantom{$\{$}f\mbox{\hspace{0.50em}}\ensuremath{\circeq}\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \equiv $\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: not² It is possible to show, for instance, that the functions \texttt{$ \lambda $\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{not}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}not}{ }\texttt{x\makebox[1.22ex][r]{$ {)} $}} and \texttt{$ \lambda $\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}x} are pointwise equal. This amounts to proving \texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}not\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}not\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \equiv $\makebox[1.22ex][c]{{~}}x}; the proof is by cases on \texttt{x}. It is not possible to show that these functions are propositionally equal.% % %paragraphName: pointwise is extensional The logical relation which we introduce in section{~}\ref{nompaSoundnessS} can be viewed as a generalized version of pointwise equality. It is extensional{:} it relates all functions that map related inputs to related outputs.% \paragraph{Everything is online} % %paragraphName: library We use some definitions from \textsc{Agda}{'}s standard library, including natural numbers, booleans, lists, and applicative functors (\texttt{pure}\index{Code!\texttt{pure}} and{~}\texttt{\makebox[1.22ex][c]{\_{}}\ensuremath{\npoasterisk}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\ensuremath{\npoasterisk}\makebox[1.22ex][c]{\_{}}}}).% % %paragraphName: gloss For the sake of conciseness, the code fragments presented in this document are sometimes not perfectly self-contained. For instance, we sometimes use the operation{~}\texttt{$ \circ $\ensuremath{^{\prime}}}, a variant of the standard composition operation{~}\texttt{$ \circ $}, which is equipped with a simpler (non-dependent) type and facilitates type reconstruction. We choose to gloss over these details. The complete code is available online{~}\cite{nompa-pouillard-11}.% \section{Introduction to the nominal approach\label{introNominal}} % %paragraphName: chapeau In order to explain what problem we are trying to solve, let us informally review how people traditionally encode abstract syntax as an algebraic data type and why these encodings are usually not satisfactory.% \subsection{Warm-up{:} the bare nominal approach\label{bareNominal}} % %paragraphName: bare description The bare approach to syntax in nominal style requires very little infrastructure to begin with. Names and binders are represented by so-called atoms. The most important operation that atoms offer is an equality test. The set of atoms is countably infinite, and there must be a way of obtaining {``}fresh{''} atoms when desired. (In the following informal discussion, we elude this aspect and simply assume that we have a number of constants of type \texttt{Atom} at hand.) Atoms are usually represented as natural numbers.% {\nopagebreak } % %code: % %comment: -- A set of atoms (could be ℕ) %Atom : Set % %-- Atom is countably infinite; here are some atoms: %-- x,y,z... could be represented by 0,1,2... %x y z f g {-...-} : Atom % %-- The equality test on atoms %_==ᴬ_ : (x y : Atom) → Bool % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}set\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}atoms\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}could\mbox{\hspace{0.50em}}be\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}Atom\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}Atom\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}countably\mbox{\hspace{0.50em}}infinite;\mbox{\hspace{0.50em}}here\mbox{\hspace{0.50em}}are\mbox{\hspace{0.50em}}some\mbox{\hspace{0.50em}}atoms{:}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}x,y,z...\mbox{\hspace{0.50em}}could\mbox{\hspace{0.50em}}be\mbox{\hspace{0.50em}}represented\mbox{\hspace{0.50em}}by\mbox{\hspace{0.50em}}0,1,2...{\nopagebreak \newline% }\vphantom{$\{$}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}z\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}-...-\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}The\mbox{\hspace{0.50em}}equality\mbox{\hspace{0.50em}}test\mbox{\hspace{0.50em}}on\mbox{\hspace{0.50em}}atoms{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{A}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: defining Tmᴬ Using the type{~}\texttt{Atom}\index{Code!\texttt{Atom}} , we can readily define algebraic data types for abstract syntax with names and binders. Our running example is the untyped $ \lambda $-calculus; its definition appears below. The type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{A}}}\index{Code!\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{A}}}} (\texttt{Tm} for {``}term{''} and \texttt{\makebox[0.61ex][l]{\textsuperscript{A}}} for {``}atom{''}) has four data constructors. The constructor{~}\texttt{V}\index{Code!\texttt{V}} is for variables and carries just an atom. The constructor{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}}} represents function application and carries two subterms. The constructor{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}\index{Code!\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}} carries an atom and a subterm in which this atom is informally considered bound. Thus, the atom carried by{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}} is informally considered a binder, whereas the atom carried by{~}\texttt{V} is a (free or bound) occurrence of a name{:} it refers to some binder. The constructor{~}\texttt{Let}\index{Code!\texttt{Let}} carries an atom and two subterms. The atom is informally considered bound in the second subterm only.% {\nopagebreak } % %code: % %comment: data Tmᴬ : Set where % V : (x : Atom) → Tmᴬ % _·_ : (t u : Tmᴬ) → Tmᴬ % ƛ : (b : Atom) (t : Tmᴬ) → Tmᴬ % Let : (b : Atom) (t u : Tmᴬ) → Tmᴬ % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: on the lack of binding info in Tmᴬ It is striking that there is no formal distinction between the atoms that represent binders and those that represent occurrences. Neither is there any indication of the scope of the binders. This calls for improvement.% % %paragraphName: 2 examples Here are two examples of terms that represent object-level syntax. They represent the identity function and the application function of the $ \lambda $-calculus.% {\nopagebreak } % %code: % %comment: -- λx. x %idTmᴬ : Tmᴬ %idTmᴬ = ƛ x (V x) % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}$ \lambda $x.\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}idTm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}idTm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- λf. λx. f x %apTmᴬ : Tmᴬ %apTmᴬ = ƛ f (ƛ x (V f · V x)) % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}$ \lambda $f.\mbox{\hspace{0.50em}}$ \lambda $x.\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}apTm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}apTm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: simple but in-adequate The strength of the {``}bare nominal{''} approach resides in its simplicity. The representation of names and binders is the same as in the concrete syntax. One important issue, though, is $ \alpha $-equivalence{:} there are multiple equivalent representations of the {``}same{''} term. Another issue is capture{:} it is easy to inadvertently change the meaning of a name by placing it in a context that happens to bind this name.% % %paragraphName: atoms are arbitrarily choosen The need for a notion of $ \alpha $-equivalence arises out of the fact that choices of atoms are arbitrary. One would like to consider that two terms represent the {``}same{''} piece of syntax when they differ only by a consistent renaming of bound names. Two such terms are said to be $ \alpha $-equivalent. For example, here are two $ \alpha $-equivalent terms{:}% {\nopagebreak } % %code: % %comment: tˣ : Tmᴬ %tˣ = ƛ x (V f · V x) %tʸ : Tmᴬ %tʸ = ƛ y (V f · V y) % ~\\~\vphantom{$\{$}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}t\makebox[0.61ex][l]{\textsuperscript{x}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}t\makebox[0.61ex][l]{\textsuperscript{y}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}t\makebox[0.61ex][l]{\textsuperscript{y}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: (x , y) ● tˣ ≡ tʸ The term{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}} is $ \alpha $-equivalent to{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{y}}} because consistently replacing the bound name{~}\texttt{x} with the name{~}\texttt{y} in the term{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}} yields the term{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{y}}}. Conversely, consistently replacing{~}\texttt{y} with{~}\texttt{x} in{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{y}}} yields{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}}. However, $ \alpha $-equivalence can be a subtle notion. The term{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{f}}} below is \emph{not} $ \alpha $-equivalent to{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}} and{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{y}}}{:}% {\nopagebreak } % %code: % %comment: tᶠ : Tmᴬ %tᶠ = ƛ f (V f · V f) % ~\\~\vphantom{$\{$}\texttt{t\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}t\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: (x , f) ● tˣ ≢ tᶠ Although replacing the bound name{~}\texttt{x} with the name{~}\texttt{f} in the term{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}} does yield{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{f}}}, this would be an \emph{inconsistent} renaming. The name{~}\texttt{f} that occurs in the renaming would be captured by the binder \texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][c]{{~}}f} that occurs in the term{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}}. Conversely, if one attempts to consistently replace{~}\texttt{f} with{~}\texttt{x} in{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{f}}}, one finds that such a replacement is permitted, but does not yield{~}\texttt{t\makebox[0.61ex][l]{\textsuperscript{x}}}.% % %paragraphName: intro α-pure Without delving any further into $ \alpha $-equivalence, let us emphasize the point of view that we adopt in this paper. Choices of bound names are purely a representation issue, so they should not be able to influence computation in an observable way. The flip-side of this slogan is, {``}good{''} computations should not observably depend on choices of bound names. This can be stated as follows{:}% \begin{quote} A function is well-behaved if, when applied to $ \alpha $-equivalent arguments, it produces $ \alpha $-equiv{\-}alent results. \end{quote} % %paragraphName: fv and rmᴬ are good Let us give a few examples of well-behaved functions. The function{~}\texttt{rm\makebox[0.61ex][l]{\textsuperscript{A}}}\index{Code!\texttt{rm\makebox[0.61ex][l]{\textsuperscript{A}}}} removes all occurrences of an atom from a list of atoms. It operates only on free names and thus does not depend on choices of bound names, hence is well-behaved. The function{~}\texttt{fv}\index{Code!\texttt{fv}}, which constructs a list of the free variables/atoms of a term is well-behaved.% {\nopagebreak } % %code: % %comment: rmᴬ : Atom → List Atom → List Atom %rmᴬ _ [] = [] %rmᴬ x (y ∷ ys) = % if x ==ᴬ y then rmᴬ x ys % else y ∷ rmᴬ x ys % ~\\~\vphantom{$\{$}\texttt{rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Atom\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Atom{\nopagebreak \newline% }\vphantom{$\{$}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}ys\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}if\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}then\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}ys{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}else\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}ys{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- rmᴬ behaves well; for instance, this holds: %test-rmᴬ : rmᴬ x [ x ] ≡ rmᴬ y [ y ] %test-rmᴬ = refl -- both sides reduce to [] % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}behaves\mbox{\hspace{0.50em}}well;\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}instance,\mbox{\hspace{0.50em}}this\mbox{\hspace{0.50em}}holds{:}{\nopagebreak \newline% }\vphantom{$\{$}test-rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{]}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{]}{\nopagebreak \newline% }\vphantom{$\{$}test-rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}refl\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}both\mbox{\hspace{0.50em}}sides\mbox{\hspace{0.50em}}reduce\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: fv : Tmᴬ → List Atom %fv (V x) = [ x ] %fv (t · u) = fv t ++ fv u %fv (ƛ x t) = rmᴬ x (fv t) %fv (Let x t u) = fv t ++ rmᴬ x (fv u) % \vphantom{$\{$}\texttt{fv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Atom{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{]}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- fv behaves well; for instance, this holds: %test-fv : fv tˣ ≡ fv tʸ %test-fv = refl -- both sides reduce to [ f ] % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}behaves\mbox{\hspace{0.50em}}well;\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}instance,\mbox{\hspace{0.50em}}this\mbox{\hspace{0.50em}}holds{:}{\nopagebreak \newline% }\vphantom{$\{$}test-fv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{x}}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{y}}{\nopagebreak \newline% }\vphantom{$\{$}test-fv\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}refl\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}both\mbox{\hspace{0.50em}}sides\mbox{\hspace{0.50em}}reduce\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}{]}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ba and cmp-ba are bad We now illustrate misbehaving functions with two examples. The function{~}\texttt{ba}\index{Code!\texttt{ba}} computes the list of {``}bound atoms{''} of a term, that is, the list of atoms that appear as binders in this term. The function{~}\texttt{cmp-ba}\index{Code!\texttt{cmp-ba}} accepts two terms and, if they are{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}-abstractions, compares the atoms bound by{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}. The codomains of these functions are respectively \texttt{List\makebox[1.22ex][c]{{~}}Atom} and \texttt{Bool}. At these types, which do not contain any binders, $ \alpha $-equivalence is just equality.% {\nopagebreak } % %code: % %comment: ba : Tmᴬ → List Atom %ba (ƛ x t) = x ∷ ba t %ba (Let x t u) = x ∷ ba t ∷ ba u %ba (t · u) = ba t ++ ba u %ba (V _) = [] % ~\\~\vphantom{$\{$}\texttt{ba\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Atom{\nopagebreak \newline% }\vphantom{$\{$}ba\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}ba\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}ba\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}ba\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: [x]≢[y] : [ x ] ≢ [ y ] %[x]≢[y] = {! omitted !} % \vphantom{$\{$}\texttt{{[}x{]}\ensuremath{\npnotequiv}{[}y{]}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{]}\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{]}{\nopagebreak \newline% }\vphantom{$\{$}{[}x{]}\ensuremath{\npnotequiv}{[}y{]}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- ba does not behave well: %test-ba : ba tˣ ≢ ba tʸ %test-ba = [x]≢[y] % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}does\mbox{\hspace{0.50em}}not\mbox{\hspace{0.50em}}behave\mbox{\hspace{0.50em}}well{:}{\nopagebreak \newline% }\vphantom{$\{$}test-ba\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{x}}\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}ba\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{y}}{\nopagebreak \newline% }\vphantom{$\{$}test-ba\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}x{]}\ensuremath{\npnotequiv}{[}y{]}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: cmp-ba : Tmᴬ → Tmᴬ → Bool %cmp-ba (ƛ x _) (ƛ y _) = x ==ᴬ y %cmp-ba _ _ = false % \vphantom{$\{$}\texttt{cmp-ba\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}cmp-ba\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}y{\nopagebreak \newline% }\vphantom{$\{$}cmp-ba\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{3.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- cmp-ba does not behave well: %test-cmp-ba : cmp-ba tˣ tˣ ≢ cmp-ba tˣ tʸ %test-cmp-ba () -- true ≢ false % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}cmp-ba\mbox{\hspace{0.50em}}does\mbox{\hspace{0.50em}}not\mbox{\hspace{0.50em}}behave\mbox{\hspace{0.50em}}well{:}{\nopagebreak \newline% }\vphantom{$\{$}test-cmp-ba\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}cmp-ba\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{x}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{x}}\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}cmp-ba\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{x}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{\textsuperscript{y}}{\nopagebreak \newline% }\vphantom{$\{$}test-cmp-ba\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}true\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: modulo α-equivalence In traditional informal proofs, $ \alpha $-equivalence is identified with equality. This means that every function must map $ \alpha $-equivalent inputs to $ \alpha $-equivalent outputs, or it does not deserve to be called a {``}function{''}. Thus, whenever one defines a function, one must prove that it is well-behaved.% \paragraph{} % %paragraphName: well-typed => α-pure, but far from this goal In this paper, we wish to exploit the type system in order to meet this proof obligation. Using logical relations and parametricity, we will be able to prove, once and for all, that well-typed functions are well-behaved (with respect to a notion of $ \alpha $-equivalence which is itself type-directed). For an appropriate definition of the type of $ \lambda $-terms, we will find that the function{~}\texttt{cmp-ba}\index{Code!\texttt{cmp-ba}} cannot be typed at all, and that the function{~}\texttt{ba}\index{Code!\texttt{ba}} can be typed only at a type that makes it harmless.% \subsection{Using well-formedness judgements\label{wfJ}} % %paragraphName: scoping rules through inductive types One way to define the scoping rules of the object language is to define a well-formedness judgement. This can be done using an inductive predicate over the structure of terms. It is a well-known technique used in the definition of type systems. The standard presentation makes use of a set of inference rules where judgements are made of an environment, a term and a type. The environment tracks the type of each introduced variable. To specify just the scoping rules, one follows the same presentation, without types. We directly focus on a formal presentation in \textsc{Agda} since inference rules (and grammars) have a direct translation into inductive types. First, one defines environments, which are just lists of atoms{:}% {\nopagebreak } % %code: % %comment: data Env : Set where ε : Env % _,_ : (Γ : Env) (x : Atom) → Env % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}Env{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10.50em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Env\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: the membership predicate Then comes the definition of the membership predicate. It states when an atom is a member of some environment. The definition consists of two rules. One rule applies when the atom is present at the first position in the environment. The other rule applies when it is present in the tail of the environment. We use \textsc{Agda} comments to give each inference rule a traditional visual appearance{:}% {\nopagebreak } % %code: % %comment: data _∈_ x : (Γ : Env) → Set where % here : ∀ {Γ} → ------------- % x ∈ (Γ , x) % % there : ∀ {Γ y} → x ∈ Γ % → ------------- % x ∈ (Γ , y) % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \in $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Env\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}here\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{2.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}-------------{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}there\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{\}{}}\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{1em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10em}}$ \rightarrow $\mbox{\hspace{0.50em}}-------------{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: the scoping predicate Finally, one can give the scoping rules of the $ \lambda $-calculus. The definition boils down to using an environment to track bound atoms, using the membership predicate at variable occurrences and pushing the binders onto the environment{:}% {\nopagebreak } % %code: % %comment: data _⊢_ Γ : Tmᴬ → Set where % V : ∀ {x} → x ∈ Γ % → --------- % Γ ⊢ V x % % _·_ : ∀ {t u} → Γ ⊢ t % → Γ ⊢ u % → ----------- % Γ ⊢ t · u % % ƛ : ∀ {t b} → Γ , b ⊢ t % → ----------- % Γ ⊢ ƛ b t % % Let : ∀ {t u b} → Γ ⊢ t % → Γ , b ⊢ u % → --------------- % Γ ⊢ Let b t u % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \vdash $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[1.22ex][r]{\}{}}\mbox{\hspace{4.50em}}$ \rightarrow $\mbox{\hspace{1em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10em}}$ \rightarrow $\mbox{\hspace{0.50em}}---------{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{\}{}}\mbox{\hspace{2.50em}}$ \rightarrow $\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10em}}$ \rightarrow $\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10em}}$ \rightarrow $\mbox{\hspace{0.50em}}-----------{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}t\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{\}{}}\mbox{\hspace{3.50em}}$ \rightarrow $\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10em}}$ \rightarrow $\mbox{\hspace{0.50em}}-----------{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}t\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{\}{}}\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10em}}$ \rightarrow $\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10em}}$ \rightarrow $\mbox{\hspace{0.50em}}---------------{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}Let\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: scoping examples We can now state that our example terms are well-scoped in the empty environment. Thanks to implicit arguments and to the definition of the membership predicate, the proof that a term is well-scoped is the term itself, expressed in de Bruijn notation (\texttt{here} and \texttt{there} respectively play the role of zero and successor).% {\nopagebreak } % %code: % %comment: ⊢id : ε ⊢ idTmᴬ %⊢id = ƛ (V here) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{$ \vdash $}id\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}idTm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \vdash $}id\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}here\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: ⊢ap : ε ⊢ apTmᴬ %⊢ap = ƛ (ƛ (V (there here) · V here)) % \vphantom{$\{$}\texttt{\makebox[1.22ex][c]{$ \vdash $}ap\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \vdash $}\mbox{\hspace{0.50em}}apTm\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \vdash $}ap\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}there\mbox{\hspace{0.50em}}here\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}here\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: these are on the side However, this technique is not exactly what we are looking for. Indeed, here, the scoping properties have to be explicitly stated on the side of each definition. We are looking for something more integrated into the types. This would enable well-formedness to be enforced in a more pervasive and automatic manner. Fortunately, this technique can be adapted so as to merge the scoping information and the term. We study this idea next.% \subsection{Well-scoped terms\label{scopedTerms}} % %paragraphName: description We now merge the inductive definition of terms and the inductive definition of the scoping predicate. Thus, we end up with an inductive type of terms that is indexed by an environment. This environment is extended at binders and queried at variable occurrences{:}% {\nopagebreak } % %code: % %comment: data Tmᴶ Γ : Set where % V : ∀ {x} → x ∈ Γ → Tmᴶ Γ % _·_ : Tmᴶ Γ → Tmᴶ Γ → Tmᴶ Γ % ƛ : ∀ b → Tmᴶ (Γ , b) → Tmᴶ Γ % Let : ∀ b → Tmᴶ Γ → Tmᴶ (Γ , b) → Tmᴶ Γ % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: sources The idea of encoding well-scopedness (and well-typedness as well) as part of the inductive definition of terms goes back at least as far as Pfenning and Lee{~}\shortcite{pfenning-lee-89}. It also appears in the original LF paper{~}\cite{harper-93} and in the nested data type approach{~}\cite{bellegarde-94,bird-paterson-99,altenkirch-reus-99}. Hence, it is by now widely known. An instance of it in the recent literature is Chlipala{'}s type-preserving compiler \shortcite{chlipala-07}.% % %paragraphName: examples One can define our two example terms in this style as well{:}% {\nopagebreak } % %code: % %comment: idTmᴶ : Tmᴶ ε %idTmᴶ = ƛ x (V here) % ~\\~\vphantom{$\{$}\texttt{idTm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}{\nopagebreak \newline% }\vphantom{$\{$}idTm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}here\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: apTmᴶ : Tmᴶ ε %apTmᴶ = ƛ f (ƛ x (V (there here) · V here)) % \vphantom{$\{$}\texttt{apTm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}{\nopagebreak \newline% }\vphantom{$\{$}apTm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}there\mbox{\hspace{0.50em}}here\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}here\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: fv The function{~}\texttt{fv}\index{Code!\texttt{fv}} can easily be adapted to this style, while the function{~}\texttt{rm\makebox[0.61ex][l]{\textsuperscript{A}}} can be reused{:}% {\nopagebreak } % %code: % %comment: fv : ∀ {Γ} → Tmᴶ Γ → List Atom %fv (V {x} _) = [ x ] %fv (t · u) = fv t ++ fv u %fv (ƛ x t) = rmᴬ x (fv t) %fv (Let x t u) = fv t ++ rmᴬ x (fv u) % ~\\~\vphantom{$\{$}\texttt{fv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Atom{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{]}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ba and cmp-ba Alas, the functions{~}\texttt{ba}\index{Code!\texttt{ba}} and{~}\texttt{cmp-ba}\index{Code!\texttt{cmp-ba}} are not rejected by this style. Their types becomes{:}% {\nopagebreak } % %code: % %comment: ba : ∀ {Γ} → Tmᴶ Γ → List Atom %cmp-ba : ∀ {Γ₁ Γ₂} → Tmᴶ Γ₁ → Tmᴶ Γ₂ → Bool % ~\\~\vphantom{$\{$}\texttt{ba\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Atom{\nopagebreak \newline% }\vphantom{$\{$}cmp-ba\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: issue1 Thus, although we have been able to formally describe the scoping rules, and to ensure that all terms are well-scoped by construction, we have not made much progress towards our goal. Indeed, two different but $ \alpha $-equivalent terms can still be distinguished.% % %paragraphName: issue2 Worse, by introducing environments and membership proofs as explicit objects, we have introduced new issues. A function that receives a term as an argument now also receives (or otherwise has access to) the environment in which this term is well-scoped. This extra information can be used by the function. For instance, here are two functions that examine the environment by pattern-matching{:}% {\nopagebreak } % %code: % %comment: fast-fv : ∀ {Γ} → Tmᴶ Γ → List Atom %fast-fv {ε} _ = [] -- for sure the term is closed %fast-fv t = fv t % ~\\~\vphantom{$\{$}\texttt{fast-fv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Atom{\nopagebreak \newline% }\vphantom{$\{$}fast-fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \epsilon $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{1em}}--\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}sure\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}term\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}closed{\nopagebreak \newline% }\vphantom{$\{$}fast-fv\mbox{\hspace{2.50em}}t\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: env-length : Env → ℕ %env-length ε = 0 %env-length (Γ , _) = 1 + env-length Γ % %env-length-Tmᴶ : ∀ {Γ} → Tmᴶ Γ → ℕ %env-length-Tmᴶ {Γ} _ = env-length Γ % \vphantom{$\{$}\texttt{env-length\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}{\nopagebreak \newline% }\vphantom{$\{$}env-length\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}0{\nopagebreak \newline% }\vphantom{$\{$}env-length\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}+\mbox{\hspace{0.50em}}env-length\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}env-length-Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}{\nopagebreak \newline% }\vphantom{$\{$}env-length-Tm\makebox[0.61ex][l]{\textsuperscript{J}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}env-length\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: issue The issue is that{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} is a concrete input to the functions{~}\texttt{fv}, \texttt{ba}, \texttt{cmp-ba}, \texttt{fast-fv}\index{Code!\texttt{fast-fv}}, and{~}\texttt{env-length-Tm\makebox[0.61ex][l]{\textsuperscript{J}}}\index{Code!\texttt{env-length-Tm\makebox[0.61ex][l]{\textsuperscript{J}}}}. It is not erased{:} it is an ordinary argument, which can be examined by the function. The fact that it is an \emph{implicit} argument offers a notational convenience, nothing more.% % %paragraphName: env-length-Tmᴶ This is not satisfactory. We would like to think of{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} as an {``}index{''}, that is, a piece of information that the type-checker keeps track of in order to reject ill-behaved code and that can be \emph{erased} prior to running the program. Here, this is impossible{:} for instance, the value of{~}\texttt{env-length-Tm\makebox[0.61ex][l]{\textsuperscript{J}}\makebox[1.22ex][c]{{~}}t} depends not just on the $ \lambda $-term that \texttt{t} represents but also on the environment{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} in which \texttt{t} is considered.% % %paragraphName: solution => abstraction In order to address these issues, we make use of abstract types. We replace environments, which have the concrete type{~}\texttt{Env} above, with \emph{worlds}, where the type{~}\texttt{World} of worlds remains abstract. Thus, worlds cannot be examined by client code. We set everything up so that worlds need not exist at runtime{:} that is, they can be erased prior to execution. However, we do not formally prove that worlds can be erased{:} we leave this issue for future work (see section{~}\ref{conclusionS}). We replace the type{~}\texttt{Atom} with two distinct types. An atom that is used in a binding position receives the abstract type{~}\texttt{Binder}. We do not equip this type with an equality test, so the function \texttt{cmp-ba} is ruled out. An atom that serves as a (free or bound) occurrence is glued together with a proof of its membership in some world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, and this pair receives the abstract type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. Because these types are abstract, we must equip them with a set of operations, otherwise they would be completely unusable. We select these operations so as to be able to prove, eventually, that well-typed functions are well-behaved. For instance, it is sound to equip the type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} with an equality test. The framework of logical relations, which we develop in section{~}\ref{nompaSoundnessS}, serves as a guide in the choice of these operations. For each operation \emph{independently}, it allows us to automatically construct the statement of a lemma that must be proved to justify that this operation is safe.% \section{The \textsc{NomPa} interface (nominal fragment)\label{nompaIface}} % %paragraphName: figure \begin{figure}[] \begin{flushleft} % %code: {\noindent}% %comment: record NomPa : Set₁ where % constructor mk % % infixr 5 _◅_ % infix 3 _⊆_ % infix 2 _#_ % % field % -- Abstract types for worlds, names, and binders % World : Set % Name : World → Set % Binder : Set % % _→ᴺ_ : (α β : World) → Set % α →ᴺ β = Name α → Name β % % field % -- Constructing worlds % ø : World % _◅_ : Binder → World → World % % -- An infinite set of binders % zeroᴮ : Binder % sucᴮ : Binder → Binder % % -- Converting back and forth between names and binders % nameᴮ : ∀ {α} b → Name (b ◅ α) % % -- There is no name in the empty world % ¬Nameø : ¬ (Name ø) % % -- Two names can be compared; a binder and a name can be compared % _==ᴺ_ : ∀ {α} (x y : Name α) → Bool % exportᴺ : ∀ {α b} → Name (b ◅ α) → Name (b ◅ ø) ⊎ Name α % % -- The fresh-for relation % _#_ : Binder → World → Set % _#ø : ∀ b → b # ø % suc# : ∀ {α b} → b # α → (sucᴮ b) # (b ◅ α) % % -- World inclusion % _⊆_ : World → World → Set % coerceᴺ : ∀ {α β} → (α ⊆ β) → (α →ᴺ β) % ⊆-refl : Reflexive _⊆_ % ⊆-trans : Transitive _⊆_ % ⊆-ø : ∀ {α} → ø ⊆ α % ⊆-◅ : ∀ {α β} b → α ⊆ β → (b ◅ α) ⊆ (b ◅ β) % ⊆-# : ∀ {α b} → b # α → α ⊆ (b ◅ α) % \vphantom{$\{$}\texttt{record\mbox{\hspace{0.50em}}NomPa\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}constructor\mbox{\hspace{0.50em}}mk{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}infixr\mbox{\hspace{0.50em}}5\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}infix\mbox{\hspace{0.50em}}3\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}infix\mbox{\hspace{0.50em}}2\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}field{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}Abstract\mbox{\hspace{0.50em}}types\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}worlds,\mbox{\hspace{0.50em}}names,\mbox{\hspace{0.50em}}and\mbox{\hspace{0.50em}}binders{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}World\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}Name\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}Binder\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}field{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}Constructing\mbox{\hspace{0.50em}}worlds{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}An\mbox{\hspace{0.50em}}infinite\mbox{\hspace{0.50em}}set\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}binders{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}zero\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}suc\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}Converting\mbox{\hspace{0.50em}}back\mbox{\hspace{0.50em}}and\mbox{\hspace{0.50em}}forth\mbox{\hspace{0.50em}}between\mbox{\hspace{0.50em}}names\mbox{\hspace{0.50em}}and\mbox{\hspace{0.50em}}binders{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}There\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}no\mbox{\hspace{0.50em}}name\mbox{\hspace{0.50em}}in\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}empty\mbox{\hspace{0.50em}}world{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}Two\mbox{\hspace{0.50em}}names\mbox{\hspace{0.50em}}can\mbox{\hspace{0.50em}}be\mbox{\hspace{0.50em}}compared;\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}binder\mbox{\hspace{0.50em}}and\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}name\mbox{\hspace{0.50em}}can\mbox{\hspace{0.50em}}be\mbox{\hspace{0.50em}}compared{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}export\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}The\mbox{\hspace{0.50em}}fresh-for\mbox{\hspace{0.50em}}relation{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}suc\#{}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}inclusion{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \subseteq $}-refl\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Reflexive\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \subseteq $}-trans\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Transitive\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \subseteq $}-\#{}\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% \end{flushleft} \caption{The \textsc{NomPa} interface (nominal fragment)\label{nompaIfaceF}} \end{figure}% % %paragraphName: intro Our library is called \textsc{NomPa}. To the client, it offers an interface whose types are abstract. Its implementation is hidden from the client. This allows us to exploit parametricity and to prove that well-typed client code is well-behaved.% % %paragraphName: fragment As announced earlier, in sections{~}\ref{nompaIface} to{~}\ref{nompaSoundnessS}, we focus on a fragment of the library, which supports programming in nominal style. The rest of the library, which supports programming in de Bruijn style as well as in combinations of the two styles, is presented in section{~}\ref{deBruijnS}. Thus, the listing that appears in Figure{~}\ref{nompaIfaceF} represents just the nominal fragment of the library.% % %paragraphName: first, data kits We now present each ingredient in turn. First, here are the building blocks needed to define algebraic data types with names and binders in a nominal style.% \subsection{Everything we need to define nominal syntax} % %paragraphName: World In order to replace environments in the definition of well-scoped terms, we introduce an abstract notion of worlds. Hence, the interface begins with an abstract type of worlds{:}% {\nopagebreak } % %code: % %comment: World : Set % ~\\~\vphantom{$\{$}\texttt{World\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Atom->Binder,Name We find it necessary to distinguish atoms that are used in a binding position and atoms that are used as (free or bound) occurrences. We refer to the former as \emph{binders} and to the latter as \emph{names}. To that end, we provide abstract types of binders and names.% % %paragraphName: Binder A binder is an atom that is meant to be used in a binding position. Internally, it is just an atom, but this fact is not exposed\index{Code!\texttt{Binder}}. Although, by traversing a term, one can gain access to all of the binders that appear in it, this does not imply that one can distinguish two $ \alpha $-equivalent terms. Indeed, the interface does not provide any means of distinguishing two binders{:} there is no equality test at type \texttt{Binder}.% {\nopagebreak } % %code: % %comment: Binder : Set % ~\\~\vphantom{$\{$}\texttt{Binder\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Name The type of names, \texttt{Name}\index{Code!\texttt{Name}}, is indexed by a world. A world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} can be thought of informally as a set of atoms. A name of type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} can be thought of as a pair of an atom and a proof that this atom is a member of the set $ \alpha $. In other words, a name has type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} if it {``}makes sense{''} in the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}.% {\nopagebreak } % %code: % %comment: Name : World → Set % ~\\~\vphantom{$\{$}\texttt{Name\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: shortcut Throughout the paper, we often use {``}name transformers{''}, that is, functions from type \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} to type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}. We write{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}} as a shorthand for this type.% % %paragraphName: worlds as sets and relations The intuitive view of worlds as sets of atoms can be referred to as the \emph{unary view} of worlds. In section{~}\ref{nompaRel}, where we study logical relations, we introduce a \emph{binary view} of worlds, whereby worlds are viewed as certain relations between sets of atoms. Although the unary view represents a good intuition (and we stick with it for the moment), the binary view is required in order to understand why (and prove that) well-typed functions are well-behaved.% % %paragraphName: _◅_ We now introduce a way of extending a world with a binder. This is analogous to the constructor{~}\texttt{\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}} of section{~}\ref{wfJ} for extending an environment with an atom.% {\nopagebreak } % %code: % %comment: _◅_ : Binder → World → World % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _◅_ (continued) If a world is thought of as a set of atoms, then the set{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} is just the union of the singleton set \{{}b\}{} and of the set{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. There is no requirement that these sets be disjoint{:} the world{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} is defined even if \texttt{b} is already a member of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. This reflects the fact that, in the nominal representation, it is permitted for two binders to bind the same name, even if one of them is nested in the other. In that case, one traditionally considers that the most recent binder {``}hides{''}, or {``}shadows{''}, the previous binder. For this reason, we pronounce{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} as {``}\texttt{b}{~}hides{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}{''}.% % %paragraphName: Tm At this point, we have everything that is needed to build data types with names and binders. The new definition of{~}\texttt{Tm}\index{Code!\texttt{Tm}} is very close to the previous one. All we have to do is use{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}}} instead of{~}\texttt{\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}}, rename{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} to{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, and use{~}\texttt{Name} instead of a pair of an atom and a membership proof{:}% {\nopagebreak } % %code: % %comment: data Tm α : Set where % V : Name α → Tm α % _·_ : Tm α → Tm α → Tm α % ƛ : ∀ b → Tm (b ◅ α) → Tm α % Let : ∀ b → Tm α → Tm (b ◅ α) → Tm α % %_→™_ : (α β : World) → Set %α →™ β = Tm α → Tm β % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}$ \rightarrow $\textsuperscript{T}\textsuperscript{m}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: note: dependent types The description of the binding constructs \texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}} and \texttt{Let} relies on dependent types{:} the binder{~}\texttt{b} is used in the type of the subterm.% % %paragraphName: size Here is a trivial example of a function that traverses a term and measures its size. It is remarkable for its simplicity{:} name abstractions are traversed without fuss. The code would be exactly the same in the bare nominal approach of section{~}\ref{bareNominal}. It is efficient{:} no renaming is involved. In comparison, in FreshML \cite{shinwell-03} or in the locally nameless approach \cite{aydemir-08,chargueraud-11-ln}, crossing a binder can have a cost that is linear in the size of the subterm. Polymorphic recursion is exploited{:} on the line that deals with{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}, the recursive call to{~}\texttt{size\makebox[1.22ex][c]{{~}}t}\index{Code!\texttt{size}} is at some inner world.% {\nopagebreak } % %code: % %comment: size : ∀ {α} → Tm α → ℕ %size (V _) = 1 %size (t · u) = 1 + size t + size u %size (ƛ _ t) = 1 + size t %size (Let _ t u) = 1 + size t + size u % ~\\~\vphantom{$\{$}\texttt{size\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}{\nopagebreak \newline% }\vphantom{$\{$}size\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}1{\nopagebreak \newline% }\vphantom{$\{$}size\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}+\mbox{\hspace{0.50em}}size\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}+\mbox{\hspace{0.50em}}size\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}size\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}+\mbox{\hspace{0.50em}}size\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}size\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}+\mbox{\hspace{0.50em}}size\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}+\mbox{\hspace{0.50em}}size\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Building binders and names} % %paragraphName: zeroᴮ, sucᴮ, _ᴮ In order to build terms, we need binders and names. Binders are introduced via two primitive operations called{~}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{B}}}\index{Code!\texttt{zero\makebox[0.61ex][l]{\textsuperscript{B}}}} and{~}\texttt{suc\makebox[0.61ex][l]{\textsuperscript{B}}}\index{Code!\texttt{suc\makebox[0.61ex][l]{\textsuperscript{B}}}}. We then lift any natural number to a binder with a cheap convenience function{:}% {\nopagebreak } % %code: % %comment: zeroᴮ : Binder %sucᴮ : Binder → Binder % %_ᴮ : ℕ → Binder %zero ᴮ = zeroᴮ %(suc n) ᴮ = sucᴮ (n ᴮ) % ~\\~\vphantom{$\{$}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}suc\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}zero\mbox{\hspace{2em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}zero\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}suc\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}n\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Binders is ℕ but limited In effect, binders are natural numbers with a restricted interface. Here, we give only zero and successor, but all of the arithmetic operations on natural numbers could be exposed as well. One key limitation, however, is that no information must be allowed to {``}leak{''} out of a binder. Hence, no equality test over binders is provided. The reason why this must be so will appear more clearly when we build the logical relation in section{~}\ref{nompaRel}.% % %paragraphName: nameᴮ,_ᴺ In order to build names, we provide a function, called{~}\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}}\index{Code!\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}}}, which turns a binder into a name.% {\nopagebreak } % %code: % %comment: nameᴮ : ∀ {α} b → Name (b ◅ α) % ~\\~\vphantom{$\{$}\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: nameᴮ limitations, idTm While{~}\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}} can turn an arbitrary binder{~}\texttt{b} into a name, it imposes that the resulting name inhabit a world of the form{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. Even though{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} can be instantiated at will, this is an important limitation. We will soon introduce a notion of world inclusion that allows overcoming this limitation (section{~}\ref{nameWeakeningS}). For the moment, we have enough building blocks to define a representation of the identity function!% {\nopagebreak } % %code: % %comment: idTm : ∀ {α} → Tm α %idTm = ƛ x (V (nameᴮ x)) where x = 0 ᴮ % ~\\~\vphantom{$\{$}\texttt{idTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}idTm\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}where\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: falseTm As another example, here is a representation of the $ \lambda $-term that represents {``}false{''} in Church{'}s encoding, that is, \texttt{$ \lambda $x.$ \lambda $x.x}. We use the binder \texttt{x} twice on purpose to show that shadowing is permitted. To type-check the variable occurrence of{~}\texttt{x}, the world{~}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} is implicitly passed to{~}\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}}, which returns a name in the world{~}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. Then, each of the two {``}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][c]{{~}}x}{''}{'}s takes away one {``}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}}{''}, so the final term inhabits the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}.% {\nopagebreak } % %code: % %comment: falseTm : ∀ {α} → Tm α %falseTm = ƛ x (ƛ x (V (nameᴮ x))) % where x = 0 ᴮ % ~\\~\vphantom{$\{$}\texttt{falseTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}falseTm\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}where\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: trueTm fail However, one faces an issue when one attempts to build a representation of the Church encoding of {``}true{''}, that is, \texttt{$ \lambda $x.$ \lambda $y.x}. The na\"{i}ve approach does not type-check{:}% {\nopagebreak } % %code: % %comment: -- this does not type-check %trueTm : ∀ {α} → Tm α %trueTm = ƛ x (ƛ y (V (nameᴮ x))) % where x = 0 ᴮ % y = 1 ᴮ % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}this\mbox{\hspace{0.50em}}does\mbox{\hspace{0.50em}}not\mbox{\hspace{0.50em}}type-check{\nopagebreak \newline% }\vphantom{$\{$}trueTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}trueTm\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}where\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4.50em}}y\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: why it fails While{~}\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][c]{{~}}x} inhabits any world of the form{~}\texttt{x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}, the context expects a name in the world{~}\texttt{y\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. We introduce means of moving a name from one world to another in section{~}\ref{nameWeakeningS}.% \paragraph{Closed terms} % %paragraphName: ø The above well-typed terms (\texttt{idTm}\index{Code!\texttt{idTm}} and{~}\texttt{falseTm}\index{Code!\texttt{falseTm}}) have no free variables. They are said to be closed. They both have type \texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. This world-polymorphic type reflects the closedness property. Indeed, if any world will do, then the empty world, written \texttt{\makebox[1.22ex][c]{$ \emptyset $}}, will do as well. Thus, \texttt{idTm} also has type{~}\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}}. Conversely, because the empty world is included in every world, we will be able to move any term from the empty world to an arbitrary world. In short, \texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}} and{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} are{~}\emph{isomorphic} types.% % %paragraphName: ¬Nameø To allow exploiting the fact that a term that inhabits the empty world must be closed, we introduce{~}\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}\index{Code!\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}}, which witnesses that there is no name in the empty world{:}% {\nopagebreak } % %code: % %comment: ø : World %¬Nameø : ¬(Name ø) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ¬Nameø In various situations, this operation enables arguing that {``}this case is impossible{''}. For instance, when writing a function that looks up a name in an environment represented as a list, one typically uses{~}\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}\index{Code!\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}} in the case where the environment is the empty list. This amounts to arguing that {``}because the name we are looking for is properly bound, the search cannot fall off the end of the environment{''}.% \subsection{World inclusion\label{nameWeakeningS}} % %paragraphName: widening description It is often necessary to widen the world which a name inhabits. Our earlier attempt to define{~}\texttt{trueTm}\index{Code!\texttt{trueTm}} illustrates this{:} for this definition to type-check, we need to widen the world of the name{~}\texttt{x}. Widening a world causes a loss of static information. For instance, we have seen that a term in the empty world must be closed. If one widens its world, then this term is no longer statically known to be closed. We call this operation {``}weakening{''} because it causes the loss of some static information. The name {``}weakening{''} is also vastly used for the same purpose when referring to typing environments.% % %paragraphName: _⊆_ and coerceᴺ To account for the multiple ways in which we could widen a world, we introduce a world inclusion predicate. In \textsc{Agda} terminology, we introduce a type{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}}} for witnesses of world inclusion. If a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is included in a world{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} then it is permitted to transport a name (and a term as well, as we shall see) from{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} to{~}\texttt{\makebox[1.22ex][c]{$ \beta $}}. The primitive operation{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}} serves this purpose. It takes an inclusion witness, a name, and returns the same name at a wider world.% {\nopagebreak } % %code: % %comment: _⊆_ : World → World → Set %coerceᴺ : ∀ {α β} → α ⊆ β → (α →ᴺ β) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: because We also introduce an alias for{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}, called{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\makebox[1.22ex][c]{\_{}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\makebox[1.22ex][c]{\_{}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}}}. It helps keep the code separate from the type-checking argument{:} the proof of world inclusion, which appears between the angle brackets, can safely be skipped by the reader.% {\nopagebreak } % %code: % %comment: infix 0 _⟨-because_-⟩ %_⟨-because_-⟩ : ∀ {α β} → Name α → α ⊆ β → Name β %_⟨-because_-⟩ n pf = coerceᴺ pf n % -- We can now write: x ⟨-because some proof -⟩ % -- Which is less noisy than: coerceᴺ (some proof) x % ~\\~\vphantom{$\{$}\texttt{infix\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\makebox[1.22ex][c]{\_{}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\makebox[1.22ex][c]{\_{}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\makebox[1.22ex][c]{\_{}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}We\mbox{\hspace{0.50em}}can\mbox{\hspace{0.50em}}now\mbox{\hspace{0.50em}}write{:}\mbox{\hspace{4.50em}}x\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}some\mbox{\hspace{0.50em}}proof\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}Which\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}less\mbox{\hspace{0.50em}}noisy\mbox{\hspace{0.50em}}than{:}\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}some\mbox{\hspace{0.50em}}proof\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}}% \paragraph{World inclusion rules} % %paragraphName: inclusion rules A set of world inclusion rules is given in figure{~}\ref{nompaIfaceF}. World inclusion is reflexive and transitive (\texttt{\makebox[1.83ex][c]{$ \subseteq $}-refl}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-refl}} and{~}\texttt{\makebox[1.83ex][c]{$ \subseteq $}-trans}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-trans}}). The empty world is a least element for world inclusion (\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}}}). For every binder{~}\texttt{b}, the operation \texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\_{}}} is covariant, which means that it preserves world inclusion (\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{\ensuremath{\triangleleft}}}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{\ensuremath{\triangleleft}}}}).% % %paragraphName: ⊆-# The last world inclusion rule,{~}\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\#{}}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\#{}}}, states that a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is included into{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} under the condition that{~}\texttt{b} is not a member of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. This condition is required for soundness. At this point, we expect that the reader might be surprised, because an interpretation of worlds as sets suggests that this condition is unnecessary{:} indeed, if{~}\texttt{$ \alpha $} is a set, then it is unconditionally a subset of{~}\texttt{\{{}{~}b{~}\}{}{~}$ \cup ${~}$ \alpha $}. This shows the limitations of this way of thinking. When we introduce logical relations in section{~}\ref{nompaRel}, we show that interpreting worlds as \emph{relations} provides a richer viewpoint and explains why this condition is necessary. Without waiting until then, the following code snippet demonstrates that in the absence of this condition one could write ill-behaved programs{:}% {\nopagebreak } % %code: % %comment: wrong : Binder → Binder → Bool %wrong x y = nameᴮ x ==ᴺ nameᴮ y ⟨-because wrongProof -⟩ % where postulate wrongProof : y ◅ ø ⊆ x ◅ y ◅ ø % ~\\~\vphantom{$\{$}\texttt{wrong\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}wrong\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}wrongProof\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}where\mbox{\hspace{0.50em}}postulate\mbox{\hspace{0.50em}}wrongProof\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: wrong is wrong As this code snippet shows, in the absence of this condition, it would be permitted to compare names in different worlds, hence to compare binders, and, finally, to distinguish two $ \alpha $-equivalent terms.% \paragraph{The {``}fresh-for{''} relation} % %paragraphName: _#_ The last inclusion rule, \texttt{\makebox[1.83ex][c]{$ \subseteq $}-\#{}}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\#{}}}, uses a {``}fresh-for{''} relation, written{~}\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}}. As suggested above, the proposition{~}\texttt{b\makebox[1.22ex][c]{{~}}\#{}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} must guarantee at least that the name{~}\texttt{b} is not a member of the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, interpreted as a set. In fact, we choose to equip the {``}fresh-for{''} relation with a strictly stronger meaning. Taking advantage of the fact that atoms are integers internally, we take{~}\texttt{b\makebox[1.22ex][c]{{~}}\#{}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} to mean that{~}\texttt{b} dominates{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, that is,{~}\texttt{b} is strictly greater than every name that inhabits{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}.% % %paragraphName: _#_axioms We introduce two rules to produce witnesses of the relation{~}\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}}. These rules appear in figure{~}\ref{nompaIfaceF}. The first rule, \texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{$ \emptyset $}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{$ \emptyset $}}}, states that every binder is fresh for the empty world. The second rule, \texttt{suc\#{}}\index{Code!\texttt{suc\#{}}}, is the reason why we equip{~}\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}} with a stronger meaning. It states that, if{~}\texttt{b} dominates{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, then the successor of \texttt{b} dominates \texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. This gives us a simple and efficient way of building {``}fresh-for{''} witnesses. We note that, although this axiomatization of the {``}fresh-for{''} relation is not complete, it has proved sufficient for our purposes.% \paragraph{Emptiness of worlds} % %paragraphName: on emptiness and (⊆ ø) The inclusion relation can express emptiness. A world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is empty if and only if{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is included in{~}\texttt{\makebox[1.22ex][c]{$ \emptyset $}}. We favor this definition of emptiness, as opposed to an intensional equality with the empty world, because it is more flexible. In section{~}\ref{napaS}, we introduce a new operation on worlds, called{~}\texttt{\makebox[1.22ex][c]{\_{}}+1}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}+1}}. We will see that the world \texttt{\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}+1} is empty, in the sense that it is included in the empty world, yet it does not reduce to{~}\texttt{\makebox[1.22ex][c]{$ \emptyset $}}\index{Code!\texttt{\makebox[1.22ex][c]{$ \emptyset $}}}.% % %paragraphName: ¬Name By combining{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}} and{~}\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}\index{Code!\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}}, we obtain a proof that, if the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is empty, then there is no name in the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. This formulation reduces the goal of obtaining a contradiction to a world inclusion goal. This is beneficial if there is automation for constructing inclusion proofs.% {\nopagebreak } % %code: % %comment: ¬Name : ∀ {α} → α ⊆ ø → ¬(Name α) %¬Name α⊆ø = ¬Nameø ∘ coerceᴺ α⊆ø % ~\\~\vphantom{$\{$}\texttt{\makebox[1.83ex][c]{$ \neg $}Name\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \neg $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Name-elim One can also introduce a version of this operation whose codomain is an arbitrary type{~}\texttt{A} instead of the empty type{:}% {\nopagebreak } % %code: % %comment: Name-elim : ∀ {A : Set} {α} → α ⊆ ø → Name α → A %Name-elim pf x = ⊥-elim (¬Name pf x) % ~\\~\vphantom{$\{$}\texttt{Name-elim\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}Name-elim\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}-elim\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \neg $}Name\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: example of Name-elim Here is a prototypical example of a function where we can avoid the case for variables{:}% {\nopagebreak } % %code: % %comment: ex-Name-elim : Tm ø → {! … !} %ex-Name-elim (t · u) = {! … !} %ex-Name-elim (ƛ b t) = {! … !} %ex-Name-elim (Let b t u) = {! … !} % -- This last case is discarded by Name-elim %ex-Name-elim (V x) = Name-elim ⊆-refl x % ~\\~\vphantom{$\{$}\texttt{ex-Name-elim\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}\makebox[2.44ex][l]{$ \ldots $}\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}ex-Name-elim\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}\makebox[2.44ex][l]{$ \ldots $}\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}ex-Name-elim\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}\makebox[2.44ex][l]{$ \ldots $}\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}ex-Name-elim\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}\makebox[2.44ex][l]{$ \ldots $}\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}This\mbox{\hspace{0.50em}}last\mbox{\hspace{0.50em}}case\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}discarded\mbox{\hspace{0.50em}}by\mbox{\hspace{0.50em}}Name-elim{\nopagebreak \newline% }\vphantom{$\{$}ex-Name-elim\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}Name-elim\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-refl\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}}% \paragraph{Relational reasoning} % %paragraphName: ⊆-Reasoning Sometimes, one must build complex inclusion witnesses. While inference would be of great effect here, we leave it for future work. For the time being, we propose a modest syntactic tool to help build inclusion witnesses. The{~}\texttt{\makebox[1.83ex][c]{$ \subseteq $}-Reasoning}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-Reasoning}} module gives access to the transitivity rule{~}\texttt{\makebox[1.83ex][c]{$ \subseteq $}-trans}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-trans}} in a style which focuses on the intermediate states of the reasoning, as opposed to the reasoning steps. The syntax is a list of worlds interspersed with inclusion witnesses. After the last world, a box{~}\texttt{\ensuremath{{\scriptstyle \blacksquare}}}\index{Code!\texttt{\ensuremath{{\scriptstyle \blacksquare}}}} ends the proof. We present an example of the use of this notation when we define{~}\texttt{trueTm}\index{Code!\texttt{trueTm}} in the next paragraph. The code for{~}\texttt{\makebox[1.83ex][c]{$ \subseteq $}-Reasoning}\index{Code!\texttt{\makebox[1.83ex][c]{$ \subseteq $}-Reasoning}} is a trick commonly used in the \textsc{Agda} standard library{~}\cite{danielsson-agdalib-11} and is given below for reference, but can safely be skipped.% {\nopagebreak } % %code: % %comment: module ⊆-Reasoning where % infix 2 _∎ % infixr 2 _⊆⟨_⟩_ % % _⊆⟨_⟩_ : ∀ α {β γ} → α ⊆ β → β ⊆ γ → α ⊆ γ % _⊆⟨_⟩_ _ = ⊆-trans % % _∎ : ∀ α → α ⊆ α % _∎ _ = ⊆-refl % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-Reasoning\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}infix\mbox{\hspace{1em}}2\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\ensuremath{{\scriptstyle \blacksquare}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}infixr\mbox{\hspace{0.50em}}2\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-trans{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\ensuremath{{\scriptstyle \blacksquare}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\ensuremath{{\scriptstyle \blacksquare}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-refl{\nopagebreak \newline% }\vphantom{$\{$}}% \paragraph{Building any term} % %paragraphName: trueTm We can now finally build all nominal terms (up to $ \alpha $-equivalence). In section{~}\ref{nominalConv}, we prove that we can build all $ \lambda $-terms by defining a function that converts a {``}bare nominal{''} $ \lambda $-term in the style of section{~}\ref{bareNominal} to a term of type{~}\texttt{Tm}. Pouillard{~}\shortcite{pouillard-12} shows that our system can encode not just the type of $ \lambda $-terms, but more generally an arbitrary nominal signature in the sense of Pitts{~}\shortcite{pitts-06}. For the time being, we focus on the term{~}\texttt{trueTm}\index{Code!\texttt{trueTm}}, and show that we can now type-check it.% {\nopagebreak } % %code: % %comment: trueTm : ∀ {α} → Tm α %trueTm {α} = ƛ x (ƛ y (V xᴺ)) % where x = 0 ᴮ % y = 1 ᴮ % xᴺ = nameᴮ x ⟨-because x ◅ ø ⊆⟨ ⊆-# (suc# (x #ø)) ⟩ % y ◅ x ◅ ø ⊆⟨ ⊆-◅ y (⊆-◅ x ⊆-ø) ⟩ % y ◅ x ◅ α ∎ -⟩ % ~\\~\vphantom{$\{$}\texttt{trueTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}trueTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}where\mbox{\hspace{0.50em}}x\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}y\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}x\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{3em}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}\#{}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{15.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{1em}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{15.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{1em}}\ensuremath{{\scriptstyle \blacksquare}}\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: trueTm conciseness The proof that is required in order to {``}move{~}\texttt{x} into the correct world{''} is involved in comparison with the simplicity of the example. Here, by fixing the empty world instead of allowing world polymorphism, we could cut the proof in half. To build larger examples, we define smart constructors which require only that one specify the distance to the binding site{~}\cite{nompa-pouillard-11}.% \subsection{Comparing and refining names} % %paragraphName: ==ᴺ While two binders cannot be compared, our interface allows comparing two names that inhabit a common world. This may seem contradictory, since one can turn binders into names. In fact, binder comparison cannot be implemented in terms of name comparison because two arbitrary binders can be turned only into names in distinct worlds.% {\nopagebreak } % %code: % %comment: _==ᴺ_ : ∀ {α} (x y : Name α) → Bool % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: exportᴺ 1 While world inclusion gives a means of weakening the type of a name, we also need a means of strengthening the type of a name, that is, of refining its world. Naturally, this requires a dynamic check. We choose to offer an operation that compares a binder{~}\texttt{b} and a name{~}\texttt{x} and refines the type of{~}\texttt{x} according to the outcome of the comparison. This operation is known as{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}}}.% % %paragraphName: exportᴺ 2 Assume that{~}\texttt{x} is in the scope of{~}\texttt{b}, that is, the name{~}\texttt{x} inhabits the world{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. The function{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}}} tests whether{~}\texttt{x} is equal to{~}\texttt{b}. If so, \texttt{x} is refined to the world{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}}, which only{~}\texttt{b} inhabits. Otherwise, it is refined to{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. In short, given a name of type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}}, the function{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}} returns the same name, with a refined type that tells whether this name stands on the{~}\texttt{b} side or on the{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} side.% {\nopagebreak } % %code: % %comment: exportᴺ : ∀ {b α} → Name (b ◅ α) → Name (b ◅ ø) ⊎ Name α %exportᴺ = maybe inj₂ (inj₁ (nameᴮ _)) ∘′ exportᴺ? % ~\\~\vphantom{$\{$}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}export\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}maybe\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \circ $\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}export\makebox[0.61ex][l]{\textsuperscript{N}}?{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: exportᴺ? Actually, the primitive operation offered by the library is the function{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}\index{Code!\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}}, which returns a result of type{~}\texttt{Maybe\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}}. The function{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}} is then built on top of{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}.% {\nopagebreak } % %code: % %comment: -- A →? B is the type of partial functions from A to B %A →? B = A → Maybe B % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}type\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}partial\mbox{\hspace{0.50em}}functions\mbox{\hspace{0.50em}}from\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}B{\nopagebreak \newline% }\vphantom{$\{$}A\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Maybe\mbox{\hspace{0.50em}}B{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: exportᴺ? : ∀ {b α} → Name (b ◅ α) →? Name α % \vphantom{$\{$}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: mcbride The idea that a dynamic check yields refined static type information is quite old, and it is difficult to determine to whom it should be attributed. It is present, for instance, in Floyd and Hoare{'}s rules for reasoning about programs \cite{floyd-67,hoare-69}. Nevertheless, it is worth noting that \texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?} is very much analogous to McBride{'}s type-refining name comparison operation \texttt{thick}{~}\cite{mcbride-unif-03}. The function \texttt{exportTm?}, which we define later on top of \texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?} (section{~}\ref{fruitS}), is analogous to McBride{'}s type-refining occur-check, but is able to deal with terms that contain binders.% % %paragraphName: exportWith On top of{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}, we also build a convenient eliminator for names. It is simply the elimination of the result of{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}.% {\nopagebreak } % %code: % %comment: exportWith : ∀ {b α A} → A → (Name α → A) → Name (b ◅ α) → A %exportWith v f = maybe f v ∘′ exportᴺ? % ~\\~\vphantom{$\{$}\texttt{exportWith\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}exportWith\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}maybe\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}$ \circ $\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}export\makebox[0.61ex][l]{\textsuperscript{N}}?{\nopagebreak \newline% }\vphantom{$\{$}}% \section{Programming on top of \textsc{NomPa} (nominal fragment)\label{usingNompa}} \subsection{Example{:} computing free variables\label{computingFreeVarS}} % %paragraphName: fv We now have enough tools to present a more interesting example, namely the function{~}\texttt{fv}, which constructs a list of the free variables of a term. At variables and applications, the code is straightforward. At a name abstraction, one easily collects the free variables of the body via a recursive call. However, this yields a list of names that inhabit the inner world of the abstraction, that is, a value of type \texttt{List\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}}. This list cannot be returned, because the codomain of{~}\texttt{fv} is declared to be{~}\texttt{List\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}}. This is fortunate, since returning this list would let the bound name leak out of its scope! As before, we rely on an auxiliary function, \texttt{rm}\index{Code!\texttt{rm}}, which removes all occurrences of a binder{~}\texttt{b} in a list of names. A new feature of{~}\texttt{rm}\index{Code!\texttt{rm}} is that it now performs type refinement in the style of (and by using) \texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}}.% {\nopagebreak } % %code: % %comment: rm : ∀ {α} b → List (Name (b ◅ α)) → List (Name α) %rm b [] = [] %rm b (x ∷ xs) with exportᴺ x -- b is implicit %... {- bound: x≡b -} | inj₁ _ = rm b xs %... {- free: x≢b -} | inj₂ x′ = x′ ∷ rm b xs % ~\\~\vphantom{$\{$}\texttt{rm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}rm\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}rm\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}xs\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}with\mbox{\hspace{0.50em}}export\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}implicit{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}bound{:}\mbox{\hspace{0.50em}}x$ \equiv $b\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}rm\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}xs{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}free{:}\mbox{\hspace{1em}}x\ensuremath{\npnotequiv}b\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}rm\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}xs{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: fv : ∀ {α} → Tm α → List (Name α) %fv (V x) = [ x ] %fv (fct · arg) = fv fct ++ fv arg %fv (ƛ b t) = rm b (fv t) %fv (Let b t u) = fv t ++ rm b (fv u) % \vphantom{$\{$}\texttt{fv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{4em}}{\char `\=}\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{]}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fct\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}arg\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}fct\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}arg{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3em}}{\char `\=}\mbox{\hspace{0.50em}}rm\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}fv\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}rm\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: rm The function{~}\texttt{rm}\index{Code!\texttt{rm}} applies{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}b\makebox[1.22ex][r]{\}{}}} to every name{~}\texttt{x} in the list and builds a list of only those{~}\texttt{x}{'}s that successfully export to the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. It exhibits a typical way of using{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}} to perform a comparison of a name against a binder together with a type refinement. This idiom is recurrent in the programs that we have written.% \subsection{Example{:} working with environments\label{workingWithEnvS}} % %paragraphName: another env example Here is another example, where we introduce the use of an environment.% {\nopagebreak } % %code: % %comment: occurs : ∀ {α} → Name α → Tm α → Bool %occurs x₀ = occ (λ y → x₀ ==ᴺ y) % where % OccEnv : World → Set % OccEnv α = Name α → Bool % extend : ∀ {α b} → OccEnv α → OccEnv (b ◅ α) % extend = exportWith false % % occ : ∀ {α} → OccEnv α → Tm α → Bool % occ Γ (V x) = Γ x % occ Γ (t · u) = occ Γ t ∨ occ Γ u % occ Γ (ƛ _ t) = occ (extend Γ) t % occ Γ (Let _ t u) = occ Γ t ∨ occ (extend Γ) u % ~\\~\vphantom{$\{$}\texttt{occurs\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}occurs\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}OccEnv\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}OccEnv\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}extend\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}OccEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}OccEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}extend\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}exportWith\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}occ\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}OccEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\vee}}\mbox{\hspace{0.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extend\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\vee}}\mbox{\hspace{0.50em}}occ\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extend\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: occurs The function{~}\texttt{occurs}\index{Code!\texttt{occurs}} tests whether the name{~}\texttt{x\makebox[0.61ex][l]{$ _{{0}} $}} occurs free in a term. An environment{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} is carried down, augmented when a binder is crossed, and looked up at variable occurrences. This environment is represented as a function of type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Bool}.% % %paragraphName: extend The definition of{~}\texttt{extend}\index{Code!\texttt{extend}} states how to look up{~}\texttt{x} in the environment{~}\texttt{extend\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Gamma $}}. (Recall that the function \texttt{extend} takes two implicit parameters, so{~}\texttt{extend\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Gamma $}} is synonymous with{~}\texttt{extend\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}b\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Gamma $}}.) To this end, one must first compare{~}\texttt{x} and{~}\texttt{b}. If{~}\texttt{x} and{~}\texttt{b} are equal, then this occurrence of{~}\texttt{x} is not free, so{~}\texttt{occ\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}V\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][r]{$ {)} $}} must return{~}\texttt{false}. If they differ, one must look up{~}\texttt{x} in{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}}. This case analysis is concisely implemented by using the function{~}\texttt{exportWith}\index{Code!\texttt{exportWith}}, which was built on top of{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}}.% % %paragraphName: nice code We believe that this code is written in a relatively natural and uncluttered style. There is no hidden cost{:} no renaming is required when a name abstraction is crossed.% % %paragraphName: safe code The type system forces us to use names in a sound way. For instance, in the definition of{~}\texttt{occ}\index{Code!\texttt{occ}}, forgetting to extend the environment when crossing a binder (that is, writing{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} instead of{~}\texttt{extend\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Gamma $}}) would cause a type error. In the definition of{~}\texttt{extend}, attempting to check whether{~}\texttt{x} occurs in{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} without first comparing{~}\texttt{x} and{~}\texttt{b} would cause a type error. Recall that the definition of the type{~}\texttt{Tm} allows a newer binding to shadow an earlier one. Our type discipline guarantees that the code works properly in the presence of shadowing.% % %paragraphName: env as list Although representing an environment as a function is a simple and elegant representation, others exist. For instance, in the case of{~}\texttt{occurs}, we could represent the environment as a list of binders{:} the code for this variant is online{~}\cite{nompa-pouillard-11}.% % %paragraphName: DataEnv Let us now consider an example where an environment is represented as an explicit data structure, namely an association list, where keys are binders. Here are the definitions of this data structure and of the environment lookup function{:}% {\nopagebreak } % %code: % %comment: data DataEnv (A : Set) : (α β : World) → Set where % ε : ∀ {β} → DataEnv A β β % _,_↦_ : ∀ {α β} (Γ : DataEnv A α β) b (x : A) % → DataEnv A (b ◅ α) β % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}DataEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \epsilon $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}DataEnv\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}DataEnv\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5em}}$ \rightarrow $\mbox{\hspace{0.50em}}DataEnv\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: lookup : ∀ {A α β} → DataEnv A α β → Name α → Name β ⊎ A %lookup ε = inj₁ %lookup (Γ , _ ↦ v) = exportWith (inj₂ v) (lookup Γ) % \vphantom{$\{$}\texttt{lookup\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}DataEnv\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}lookup\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}\mbox{\hspace{6em}}{\char `\=}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}{\nopagebreak \newline% }\vphantom{$\{$}lookup\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\mbox{\hspace{0.50em}}v\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}exportWith\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}v\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}lookup\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: DataEnv and lookup The type{~}\texttt{DataEnv\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}\index{Code!\texttt{DataEnv}} is the type of an environment, or environment fragment, where every name in the environment is associated with a datum of type{~}\texttt{A}. We refer to the parameter{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} as the {``}inner world{''}, and to the parameter{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} as the {``}outer world{''}. The outer world can be thought of as the world that exists before the binders in the environment are introduced. The inner world is the world obtained after these binders are introduced. The expression{~}\texttt{lookup\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][c]{{~}}x} \index{Code!\texttt{lookup}} looks up the name{~}\texttt{x} in the environment{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}}. The name{~}\texttt{x} must make sense in the scope of{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}}, that is,{~}\texttt{x} must inhabit the inner world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. If{~}\texttt{x} is found among the bindings, then the information associated with{~}\texttt{x} is returned. This information has type \texttt{A}. If{~}\texttt{x} is not found among the bindings, then{~}\texttt{x} is returned, with a more precise type{:} indeed, since{~}\texttt{x} is not among the names introduced by{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}}, it must make sense outside{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}}, that is, in the outer world{~}\texttt{\makebox[1.22ex][c]{$ \beta $}}.% % %paragraphName: fv with DataEnv We illustrate the use of{~}\texttt{DataEnv} with an alternative definition of the function{~}\texttt{fv}\index{Code!\texttt{fv}}. Here, the payload type parameter{~}\texttt{A} is instantiated with the unit type{~}\texttt{\makebox[1.22ex][c]{$ \top $}}. This variant avoids the need to take the bound atoms off the list by not inserting them in the first place. At variable occurrences, we use{~}\texttt{lookup} to test whether the name is free or bound. If it is free, we wrap it in a singleton list (using the function{~}\texttt{{[}\makebox[1.22ex][c]{\_{}}{]}}) and return it. If it is bound, we ignore it and return an empty list (using the function{~}\texttt{const\makebox[1.22ex][c]{{~}}{[}{]}}). The function \texttt{{[}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}{]}\ensuremath{^{\prime}}} allows eliminating the sum produced by{~}\texttt{lookup}. At every other node, we simply carry out a recursive traversal. Whenever a name abstraction is entered, the current environment{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} is extended with the bound name{~}\texttt{b}.% {\nopagebreak } % %code: % %comment: fv' : ∀ {α β} → DataEnv ⊤ α β → Tm α → List (Name β) %fv' Γ (V x) = [ [_] , const [] ]′ (lookup Γ x) %fv' Γ (t · u) = fv' Γ t ++ fv' Γ u %fv' Γ (ƛ b t) = fv' (Γ , b ↦ _) t %fv' Γ (Let b t u) = fv' Γ t ++ fv' (Γ , b ↦ _) u % ~\\~\vphantom{$\{$}\texttt{fv{'}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}DataEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \top $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}{[}\makebox[1.22ex][c]{\_{}}{]}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}const\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{0.50em}}{]}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}lookup\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: fv : ∀ {α} → Tm α → List (Name α) %fv = fv' ε % \vphantom{$\{$}\texttt{fv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}fv{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \epsilon $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: more efficient environments Admittedly, neither functions nor lists are the most efficient representation of environments. It would be nice to be able to implement environments using, say, balanced binary search trees. At the moment, this cannot be done by the user, outside our library. The reason is, the library does not expose a total ordering on names. We cannot expose such an ordering{:} the logical relation which we build in section{~}\ref{nompaSoundnessS} forbids it. The library could, however, offer an efficient implementation of association maps whose keys are names{:} this would be permitted by the logical relation. We leave a deeper study of this issue for future work.% \subsection{Example{:} comparing terms\label{nompaCmpTermS}} % %paragraphName: goal We now show how terms can be tested for $ \alpha $-equivalence, or, more generally, for $ \alpha $-equivalence up to a certain relation over their free names.% % %paragraphName: type |Cmp| We first define the type{~}\texttt{\textbar{}Cmp\textbar{}\makebox[1.22ex][c]{{~}}F} of functions that compare \texttt{F}-structures, where{~}\texttt{F} is an indexed type. In the following, the type{~}\texttt{Ix} of indices will be instantiated with{~}\texttt{World}, and the type{~}\texttt{F} will be instantiated with{~}\texttt{Name} or{~}\texttt{Tm}.% {\nopagebreak } % %code: % %comment: |Cmp| : ∀ {Ix} (F : Ix → Set) (i j : Ix) → Set %|Cmp| F i j = F i → F j → Bool % ~\\~\vphantom{$\{$}\texttt{\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}Ix\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}F\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ix\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}i\mbox{\hspace{0.50em}}j\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ix\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}i\mbox{\hspace{0.50em}}j\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}i\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}j\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: extendNameCmp and cmpTm In order to compare two terms, we carry down an environment, which tells us how to compare two names. At name occurrences, we consult this environment. At application nodes, we carry it down. At name abstractions, we must extend it. To this end, we define the function{~}\texttt{extendNameCmp}\index{Code!\texttt{extendNameCmp}}. This function receives a name comparator{~}\texttt{f} for worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}}, a name{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} in the world{~}\texttt{b\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}}, and a name{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}} in the world{~}\texttt{b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}}. Then, the function{~}\texttt{extendNameCmp} attempts to export{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} through{~}\texttt{b\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}} through{~}\texttt{b\makebox[0.61ex][l]{$ _{{2}} $}}. If both attempts succeed, then we can use{~}\texttt{f} to compare{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} and {~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}}. If both attempts fail, then{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} is{~}\texttt{b\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}} is{~}\texttt{b\makebox[0.61ex][l]{$ _{{2}} $}}; hence, each of these two names is equal to the nearest enclosing binder, and we return{~}\texttt{true}. If one attempt succeeds and the other fails, then we return{~}\texttt{false}.% {\nopagebreak } % %code: % %comment: extendNameCmp : ∀ {α₁ α₂ b₁ b₂} → |Cmp| Name α₁ α₂ % → |Cmp| Name (b₁ ◅ α₁) (b₂ ◅ α₂) %extendNameCmp f x₁ x₂ % with exportᴺ? x₁ | exportᴺ? x₂ %... | just x₁′ | just x₂′ = f x₁′ x₂′ %... | nothing | nothing = true %... | _ | _ = false % ~\\~\vphantom{$\{$}\texttt{extendNameCmp\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{15em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}extendNameCmp\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}with\mbox{\hspace{0.50em}}export\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{1.50em}}\textbar{}\mbox{\hspace{0.50em}}export\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{1em}}\textbar{}\mbox{\hspace{0.50em}}just\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\ensuremath{^{\prime}}\mbox{\hspace{3em}}\textbar{}\mbox{\hspace{0.50em}}just\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\ensuremath{^{\prime}}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\ensuremath{^{\prime}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{1em}}\textbar{}\mbox{\hspace{0.50em}}nothing\mbox{\hspace{3em}}\textbar{}\mbox{\hspace{0.50em}}nothing\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}true{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{1em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{6em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{4.50em}}{\char `\=}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: cmpTm : ∀ {α₁ α₂} (Γ : |Cmp| Name α₁ α₂) → |Cmp| Tm α₁ α₂ %cmpTm Γ (V x₁) (V x₂) = Γ x₁ x₂ %cmpTm Γ (t₁ · u₁) (t₂ · u₂) = cmpTm Γ t₁ t₂ ∧ cmpTm Γ u₁ u₂ %cmpTm Γ (ƛ _ t₁) (ƛ _ t₂) = cmpTm (extendNameCmp Γ) t₁ t₂ %cmpTm Γ (Let b₁ t₁ u₁) (Let b₂ t₂ u₂) % = cmpTm Γ t₁ t₂ ∧ cmpTm (extendNameCmp Γ) u₁ u₂ %cmpTm _ _ _ = false % \vphantom{$\{$}\texttt{cmpTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extendNameCmp\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extendNameCmp\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{5em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{5em}}{\char `\=}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: positional comparison In the above code, there is no need to compare names or binders found in the first term with names or binders found in the second term. Instead, we consider that two bound names are equal if and only if they were bound at the same time. In short, bound names are compared positionally. This explains why the lack of a function that compares binders is not a problem.% % %paragraphName: _==ᵀᵐ_ The function{~}\texttt{cmpTm}\index{Code!\texttt{cmpTm}} must be able to accept two terms in different worlds for the recursion to go through successfully. In the end, though, this generality is often unnecessary. By supplying the name comparison function{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}}} as the initial name comparator, we obtain a specialized version of{~}\texttt{cmpTm}\index{Code!\texttt{cmpTm}}, baptised{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{T}}\makebox[0.61ex][l]{\textsuperscript{m}}\makebox[1.22ex][c]{\_{}}}. This homogeneous comparison function tests whether its arguments are $ \alpha $-equivalent.% {\nopagebreak } % %code: % %comment: _==ᵀᵐ_ : ∀ {α} → Tm α → Tm α → Bool %_==ᵀᵐ_ = cmpTm _==ᴺ_ % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{T}}\makebox[0.61ex][l]{\textsuperscript{m}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{T}}\makebox[0.61ex][l]{\textsuperscript{m}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}cmpTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Kits and traversals\label{kitsAndTraversals}} % %paragraphName: the need We have seen that working with worlds requires explicitly moving names from world to world using operations like{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}} and{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}. It quickly appears that it is necessary to lift these operations to user-defined algebraic data types, such as the type{~}\texttt{Tm}, so that user-defined data structures can be moved from world to world. More generally, a number of operations on names can be lifted to user-defined algebraic data types.% % %paragraphName: traversal and traversal kits Our experience with the library leads us to emphasize two points. First, in most of the operations on terms that we are about present, only the parts that deal with the binding structure vary. The code that carries out the traversal is fixed and can be written only once. Second, the parts that are specific to each operation can be made reusable, so as to work not only with the generic traversal but with custom traversals as well.% % %paragraphName: announce In order to share code and separate concerns, we introduce some infrastructure, which we later instantiate for the type{~}\texttt{Tm}.% \subsubsection{Traversal kits} % %paragraphName: traversal kits We begin by introducing the notion of a \emph{traversal kit}\index{traversal kit}. A traversal kit is a record whose components indicate how a traversal should deal with names and binders.% % %paragraphName: kit Env Res The first component of a traversal kit is the parameterized type{~}\texttt{Env} of the environments that are carried down during the traversal. We are interested in traversals that perform some kind of translation. Thus, in an environment of type{~}\texttt{Env\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}, the parameter{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} represents the world which the original term inhabits, while the parameter{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} represents the world which the transformed term inhabits. Such an environment maps names of type \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} to data of type{~}\texttt{Res\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}, where the type{~}\texttt{Res} is itself a component of the traversal kit, so that it can vary from application to application.% % %paragraphName: kit tr The last three components of a traversal kit are functions. The function{~}\texttt{trName}\index{Code!\texttt{trName}} looks up a name in the environment, and is typically used when the traversal reaches an occurrence of a variable. The function{~}\texttt{trBinder}\index{Code!\texttt{trBinder}} indicates how to translate a binder. For instance, this function could be the identity. Or, if there is a need to avoid capture (as is the case when defining capture-avoiding substitution), it could be a function that returns a fresh binder. The function{~}\texttt{trBinder}\index{Code!\texttt{trBinder}} has access to the environment, which, as we will see, can encapsulate a supply of fresh binders. Finally, the function{~}\texttt{extEnv}\index{Code!\texttt{extEnv}} indicates how to extend the environment when descending under a binder. It is worth noting that, while the source world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is extended with the binder{~}\texttt{b}, the destination world{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} is extended with its image through the translation, that is, \texttt{trBinder\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][c]{{~}}b}.% {\nopagebreak } % %code: % %comment: record TrKit (Env : (α β : World) → Set) % (Res : World → Set) : Set where % constructor mk % field % trName : ∀ {α β} → Env α β → Name α → Res β % trBinder : ∀ {α β} → Env α β → Binder → Binder % extEnv : ∀ {α β} b (Δ : Env α β) % → Env (b ◅ α) (trBinder Δ b ◅ β) % ~\\~\vphantom{$\{$}\texttt{record\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Env\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{$ {(} $}Res\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}constructor\mbox{\hspace{0.50em}}mk{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}field{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}trName\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Res\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}trBinder\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}extEnv\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{11.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trBinder\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: a series of kits In the following, we build a number of traversal kits. The coercing kit allows applying a world inclusion witness. The renaming kit allows applying a potentially effectful function of names to names. The substitution kit allows applying a function of names to terms. We also present a few ways of building new kits out of existing kits.% \subsubsection{The coercing kit\label{coercingKitS}} % %paragraphName: coerceKit Our first kit, called{~}\texttt{coerceKit}\index{Code!\texttt{coerceKit}}, is simple and to the point. Its environment type is{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}}. Its result type is{~}\texttt{Name}. The action on names is{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}. The action on binders is the identity, which means that this kit does not perform any kind of renaming or freshening. Finally, the environment extension operation is just the world inclusion rule{~}\texttt{\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{\ensuremath{\triangleleft}}}.% {\nopagebreak } % %code: % %comment: coerceKit : TrKit _⊆_ Name %coerceKit = mk coerceᴺ (const id) ⊆-◅ % ~\\~\vphantom{$\{$}\texttt{coerceKit\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}Name{\nopagebreak \newline% }\vphantom{$\{$}coerceKit\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}mk\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}const\mbox{\hspace{0.50em}}id\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{\ensuremath{\triangleleft}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: using coerceKit To illustrate the use of{~}\texttt{coerceKit}, we lift{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}} from names to terms. Here is an inductive definition of the function{~}\texttt{coerceTm}{:}% {\nopagebreak } % %code: % %comment: module CoerceTmWithCoerceKit where % open TrKit coerceKit % % coerceTm : ∀ {α β} → α ⊆ β → α →™ β % coerceTm Δ (V x) = V (trName Δ x) % coerceTm Δ (t · u) = coerceTm Δ t · coerceTm Δ u % coerceTm Δ (ƛ b t) = ƛ (trBinder Δ b) % (coerceTm (extEnv b Δ) t) % coerceTm Δ (Let b t u) = Let (trBinder Δ b) (coerceTm Δ t) % (coerceTm (extEnv b Δ) u) % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}CoerceTmWithCoerceKit\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}open\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}coerceKit{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}coerceTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trName\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trBinder\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{14.50em}}\makebox[1.22ex][l]{$ {(} $}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extEnv\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}Let\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trBinder\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}b\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{15.50em}}\makebox[1.22ex][l]{$ {(} $}coerceTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extEnv\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: coerceTm The function{~}\texttt{coerceTm}\index{Code!\texttt{coerceTm}} takes an inclusion witness and an input term. The inclusion witness is carried down during the traversal, used at names, and extended at abstractions. In this code, because of the declaration{~}\texttt{open\makebox[1.22ex][c]{{~}}TrKit\makebox[1.22ex][c]{{~}}coerceKit}, the variable{~}\texttt{trName} refers to the{~}\texttt{trName} component of{~}\texttt{coerceKit}, which by definition is{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}. Similarly, \texttt{trBinder} is the identity, and{~}\texttt{extEnv} is{~}\texttt{\makebox[1.83ex][c]{$ \subseteq $}-}.% % %paragraphName: towards a generic traversal We have formulated this code in such a way that the traversal is actually independent of which traversal kit is used. Permitting such a formulation is the reason why we introduced traversal kits in the first place. We will soon see that it is possible to define a generic traversal function and to redefine{~}\texttt{coerceTm} as an instance of the generic traversal with the coercing kit (sections{~}\ref{traversalS} and{~}\ref{fruitS}).% \subsubsection{The renaming kits\label{renameKitS}} % %paragraphName: Supply We now wish to define a {``}renaming kit{''} that allows applying an arbitrary function of names to names to (the free names of) a term. In order to avoid capture, we must perform {``}freshening{''}, that is, replace the binders found in the original term with fresh binders. For this purpose, we introduce the concept of a name supply\index{Code!\texttt{Supply}}. A name supply for the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is just a pair of a binder, called{~}\texttt{seed\makebox[0.61ex][l]{\textsuperscript{B}}}\index{Code!\texttt{seed\makebox[0.61ex][l]{\textsuperscript{B}}}}, and a proof that{~}\texttt{seed\makebox[0.61ex][l]{\textsuperscript{B}}} is fresh for{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}{:}% {\nopagebreak } % %code: % %comment: record Supply α : Set where % constructor _,_ % field % seedᴮ : Binder % seed# : seedᴮ # α % ~\\~\vphantom{$\{$}\texttt{record\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}constructor\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}field{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}seed\#{}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: zeroˢ, sucˢ It may seem surprising that a single fresh binder can be thought of as a name supply. The reason is that, thanks to the operation{~}\texttt{suc\#{}} (which was presented in section{~}\ref{nompaIface}), a single fresh binder gives rise to an infinite stream of fresh binders. The function{~}\texttt{suc\makebox[0.61ex][l]{\textsuperscript{s}}}\index{Code!\texttt{suc\makebox[0.61ex][l]{\textsuperscript{s}}}}, defined below, helps do this{:} it increments both the seed and the {``}fresh-for{''} proof. The constant{~}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{s}}} is an initial name supply.% {\nopagebreak } % %code: % %comment: zeroˢ : Supply ø %zeroˢ = 0 ᴮ , 0 ᴮ #ø % ~\\~\vphantom{$\{$}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}zero\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\#{}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: sucˢ : ∀ {α} → (s : Supply α) → Supply (Supply.seedᴮ s ◅ α) %sucˢ (seedᴮ , seed#) = sucᴮ seedᴮ , suc# seed# % \vphantom{$\{$}\texttt{suc\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}s\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Supply.seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}suc\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}seed\#{}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}suc\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}suc\#{}\mbox{\hspace{0.50em}}seed\#{}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: fresh name generation In our system, a world-polymorphic function that does not need to generate fresh names is parameterized over just a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, whereas a world-polymorphic function that needs to generate fresh names is typically parameterized over a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} and a name supply of type{~}\texttt{Supply\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}.% % %paragraphName: SubstEnv We are now in a position to define a renaming kit. We first define its environment type, \texttt{SubstEnv\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}\index{Code!\texttt{SubstEnv}}. It is a record type. Its first two components, \texttt{Res} and{~}\texttt{trName}\index{Code!\texttt{trName}}, specify an action on names. This action is chosen by the end user{:} hence, the renaming kit is parametric in it. The last component of the environment, \texttt{supply}\index{Code!\texttt{supply}}, is a name supply for the destination world{~}\texttt{\makebox[1.22ex][c]{$ \beta $}}. This reflects the fact that we need to create fresh binders in the transformed term.% {\nopagebreak } % %code: % %comment: record SubstEnv (Res : World → Set) α β : Set where % constructor _,_ % field trName : Name α → Res β % supply : Supply β % open Supply supply public % ~\\~\vphantom{$\{$}\texttt{record\mbox{\hspace{0.50em}}SubstEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Res\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}constructor\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}field\mbox{\hspace{0.50em}}trName\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Res\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}supply\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}open\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}supply\mbox{\hspace{0.50em}}public{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: renameKit Res The renaming kit,{~}\texttt{renameKit}\index{Code!\texttt{renameKit}}, is defined as follows. First, we let{~}\texttt{Res} be{~}\texttt{Name}.% {\nopagebreak } % %code: % %comment: RenameEnv : (α β : World) → Set %RenameEnv = SubstEnv Name % ~\\~\vphantom{$\{$}\texttt{RenameEnv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}RenameEnv\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}SubstEnv\mbox{\hspace{0.50em}}Name{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: renameKit tr Then, we provide definitions for the functions{~}\texttt{trName}, \texttt{trBinder}, and{~}\texttt{extEnv}. The definition of{~}\texttt{trName} is trivial{:} it is the{~}\texttt{trName} component of the environment. The function{~}\texttt{trBinder} uses the{~}\texttt{supply} component of the environment to obtain a fresh binder. The definition of{~}\texttt{extEnv} is the most involved part of the kit. Because an environment is a pair of an action{~}\texttt{trName} and a supply, the job of{~}\texttt{extEnv} is to lift these two components through a binder. The manner in which{~}\texttt{trName} is lifted, so as to obtain a new function{~}\texttt{trName\ensuremath{^{\prime}}}, is depicted in figure{~}\ref{liftingTrName}. The function{~}\texttt{trName\ensuremath{^{\prime}}} takes a name and uses{~}\texttt{exportWith} to test whether this name is bound or free. If this name is bound (that is, equal to{~}\texttt{b}), then the fresh binder that was chosen to stand for{~}\texttt{b}, namely{~}\texttt{seed\makebox[0.61ex][l]{\textsuperscript{B}}}, is returned. If this name is free, then{~}\texttt{exportWith} refines its type to{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}, which allows us to apply{~}\texttt{trName} to it. This produces a name in the world{~}\texttt{\makebox[1.22ex][c]{$ \beta $}}, which is then imported back using{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}. This call to{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}} is valid only because{~}\texttt{seed\makebox[0.61ex][l]{\textsuperscript{B}}} is known to be fresh for the destination world.% {\nopagebreak } % %code: % %comment: renameKit : TrKit RenameEnv Name %renameKit = mk SubstEnv.trName trBinder extEnv % where % -- Each binder is translated to a fresh binder % trBinder : ∀ {α β} → RenameEnv α β → Binder → Binder % trBinder (_ , (seedᴮ , _)) _ = seedᴮ % % extEnv : ∀ {α β} b (Δ : RenameEnv α β) % → RenameEnv (b ◅ α) (_ ◅ β) % extEnv _ (trName , (seedᴮ , seed#β)) % = (trName′ , (sucˢ (seedᴮ , seed#β))) % where % trName′ = exportWith % (nameᴮ seedᴮ) -- bound % (coerceᴺ (⊆-# seed#β) ∘ trName) -- free % ~\\~\vphantom{$\{$}\texttt{renameKit\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}RenameEnv\mbox{\hspace{0.50em}}Name{\nopagebreak \newline% }\vphantom{$\{$}renameKit\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}mk\mbox{\hspace{0.50em}}SubstEnv.trName\mbox{\hspace{0.50em}}trBinder\mbox{\hspace{0.50em}}extEnv{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}Each\mbox{\hspace{0.50em}}binder\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}translated\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}fresh\mbox{\hspace{0.50em}}binder{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}trBinder\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}RenameEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}trBinder\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}seed\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}extEnv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}RenameEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{13em}}$ \rightarrow $\mbox{\hspace{0.50em}}RenameEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}extEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trName\mbox{\hspace{1.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{3em}},\mbox{\hspace{0.50em}}seed\#{}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trName\ensuremath{^{\prime}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}seed\#{}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}trName\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}exportWith{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}seed\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}bound{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9em}}\makebox[1.22ex][l]{$ {(} $}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-\#{}\mbox{\hspace{0.50em}}seed\#{}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}trName\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}free{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: figure \begin{figure}[] \begin{flushleft} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=3cm]\path node (trName){\texttt{trName\makebox[1.22ex][c]{{~}}{:}}}; \path node (trNameP)[below of=trName]{\texttt{trName\ensuremath{^{\prime}}\makebox[1.22ex][c]{{~}}{:}}}; \path node (A)[right of=trName]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}}; \path node (B)[right of=A]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}}; \path node (bA)[right of=trNameP]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}}}; \path node (TbB)[right of=bA]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}}}; \path[->] (A) edge node [right]{}(B); \path[->] (bA) edge node [right]{\texttt{exportWith}}(A); \path[->] (bA) edge node [right]{}(TbB); \path[->] (B) edge node [right]{\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}}(TbB); \end{scope} \end{tikzpicture} \end{center}% \end{flushleft} \caption{Lifiting \texttt{trName}\label{liftingTrName}} \end{figure}% % %paragraphName: renameAKit Because we have defined{~}\texttt{Res} to be{~}\texttt{Name}, the above renaming kit works with \emph{total} functions of names to names. In order to lift the function{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?} from names to terms, we need to deal with \emph{partial} functions as well. This leads us to define another renaming kit, which is parameterized over a notion of effectful computation, that is, over an applicative functor. An applicative functor{~}\cite{mcbride-paterson-08} is halfway between a functor and a monad. Like a monad, an applicative functor has a unit, called{~}\texttt{pure}\index{Code!\texttt{pure}}. The function{~}\texttt{pure} allows viewing a pure value as a potentially effectful one. Furthermore, an applicative functor comes with an effectful application, written{~}\texttt{\makebox[1.22ex][c]{\_{}}\ensuremath{\npoasterisk}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\ensuremath{\npoasterisk}\makebox[1.22ex][c]{\_{}}}}. This operation takes an effectful function, an effectful argument, and produces an effectful result. As an illustration, here is how one uses an applicative functor to map an effectful function over a list{:}% {\nopagebreak } % %code: % %comment: module MapA {E} (E-app : Applicative E) where % open Applicative E-app % % mapA : {A B : Set} → (A → E B) → List A → E (List B) % mapA _ [] = pure [] % mapA f (x ∷ xs) = pure _∷_ ⊛ f x ⊛ mapA f xs % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}MapA\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E-app\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}open\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E-app{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}mapA\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}B\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}List\mbox{\hspace{0.50em}}B\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}mapA\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}mapA\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}xs\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{{:}{:}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}mapA\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}xs{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: renameAKit In order to define our second and more general renaming kit, we reuse the type{~}\texttt{SubstEnv}, but define the result type{~}\texttt{Res} to be{~}\texttt{E\makebox[1.22ex][c]{{~}}$ \circ $\makebox[1.22ex][c]{{~}}Name}, as opposed to just{~}\texttt{Name}. The construction is parameterized with the applicative functor{~}\texttt{E}. This allows us to support several kinds of effects. The code for{~}\texttt{renameAKit}\index{Code!\texttt{renameAKit}} is similar to that of{~}\texttt{renameKit}, so we omit it and show only its type{:}% {\nopagebreak } % %code: % %comment: RenameAEnv : (E : Set → Set) (α β : World) → Set %RenameAEnv E = SubstEnv (E ∘ Name) % %renameAKit : ∀ {E} → Applicative E → % TrKit (RenameAEnv E) (E ∘ Name) %renameAKit = {! code similar to renameKit omitted !} % ~\\~\vphantom{$\{$}\texttt{RenameAEnv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}RenameAEnv\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}SubstEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}Name\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}renameAKit\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{7.50em}}TrKit\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}RenameAEnv\mbox{\hspace{0.50em}}E\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}Name\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}renameAKit\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}code\mbox{\hspace{0.50em}}similar\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}renameKit\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsubsection{The substitution kit} % %paragraphName: substKit We now generalize the renaming kit along a different direction. Instead of actions that map names to names, we now wish to work with actions that map names to {``}terms{''}. The type family for terms does not have to be{~}\texttt{Tm}{:} we parameterize the substitution kit over a type family{~}\texttt{F}. We require that{~}\texttt{F} be equipped with two operations. First, we require an operation that turns a name into a term. We call this operation{~}\texttt{V}, by analogy with the data constructor{~}\texttt{V} of the type{~}\texttt{Tm}. Second, we require a way of coercing a term from one world to another. The substitution kit defines the type of environments to be{~}\texttt{SubstEnv\makebox[1.22ex][c]{{~}}F}. The use of{~}\texttt{SubstEnv} reflects the fact that we need to generate fresh binders in order to avoid capture, and the use of the parameter{~}\texttt{F} reflects the fact that names are mapped to terms.\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\ensuremath{\stackrel{\circ}{\rightarrow}}\makebox[1.22ex][c]{\_{}}}}\index{Code!\texttt{Coerce}}.% {\nopagebreak } % %code: % %comment: -- Index-respecting functions %F ⇴ G = ∀ {i} → F i → G i % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}Index-respecting\mbox{\hspace{0.50em}}functions{\nopagebreak \newline% }\vphantom{$\{$}F\mbox{\hspace{0.50em}}\ensuremath{\stackrel{\circ}{\rightarrow}}\mbox{\hspace{0.50em}}G\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}i\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}i\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}G\mbox{\hspace{0.50em}}i{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- The type for `coerce' on an F-term %Coerce F = ∀ {α β} → α ⊆ β → F α → F β % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}The\mbox{\hspace{0.50em}}type\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}{`}coerce{'}\mbox{\hspace{0.50em}}on\mbox{\hspace{0.50em}}an\mbox{\hspace{0.50em}}F-term{\nopagebreak \newline% }\vphantom{$\{$}Coerce\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: substKit : ∀ {F} % (V : Name ⇴ F) % (coerceF : Coerce F) % → TrKit (SubstEnv F) F %substKit = {! code similar to renameKit omitted !} % \vphantom{$\{$}\texttt{substKit\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}F\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{3.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\ensuremath{\stackrel{\circ}{\rightarrow}}\mbox{\hspace{0.50em}}F\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{$ {(} $}coerceF\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Coerce\mbox{\hspace{0.50em}}F\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}SubstEnv\mbox{\hspace{0.50em}}F\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}F{\nopagebreak \newline% }\vphantom{$\{$}substKit\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}code\mbox{\hspace{0.50em}}similar\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}renameKit\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsubsection{Other kits and combinators} % %paragraphName: others kits We build a few other kits and combinators{~}\cite{nompa-pouillard-11}. For instance,{~}\texttt{$ \circ $-Kit}\index{Code!\texttt{$ \circ $-Kit}} composes two kits by pairing the two environments and composing their operations. Another combinator,{~}\texttt{starKit}\index{Code!\texttt{starKit}}, takes a kit whose environments have type{~}\texttt{Env} and builds a kit whose environments have type{~}\texttt{Star\makebox[1.22ex][c]{{~}}Env}, where{~}\texttt{Star} is \textsc{Agda}{'}s reflexive and transitive closure operator. Finally, the combinator{~}\texttt{mapKit}\index{Code!\texttt{mapKit}} allows pre-composing a function (of names to names) and post-composing a function (of results to results) with a kit to obtain a new kit. Here is the definition of{~}\texttt{mapKit}{:}% {\nopagebreak } % %code: % %comment: mapKit : ∀ {Env F G} (f : Name ⇴ Name) (g : F ⇴ G) % → TrKit Env F → TrKit Env G %mapKit f g kit = mk (λ Δ → g ∘ trName Δ ∘ f) trBinder extEnv % where open TrKit kit % ~\\~\vphantom{$\{$}\texttt{mapKit\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}Env\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}G\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\ensuremath{\stackrel{\circ}{\rightarrow}}\mbox{\hspace{0.50em}}Name\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}g\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}\ensuremath{\stackrel{\circ}{\rightarrow}}\mbox{\hspace{0.50em}}G\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}G{\nopagebreak \newline% }\vphantom{$\{$}mapKit\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}kit\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}mk\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}trName\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}trBinder\mbox{\hspace{0.50em}}extEnv{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}where\mbox{\hspace{0.50em}}open\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}kit{\nopagebreak \newline% }\vphantom{$\{$}}% \subsubsection{A reusable traversal\label{traversalS}} % %paragraphName: TraverseTm We now write a term-to-term transformation function that works with an arbitrary effect and with an arbitrary {``}name-to-term{''} kit. It is essentially a {``}map{''} function over terms{:} it maps terms to terms, and transforms names and binders as specified by the kit. More precisely, the function{~}\texttt{trTm}\index{Code!\texttt{trTm}} traverses the term, carrying an environment. Name occurrences are transformed into terms via{~}\texttt{trName}. (The data constructor{~}\texttt{V} is not necessarily preserved). Binders are transformed using{~}\texttt{trBinder}. (In the code that follows, this information is implicit and is reconstructed by \textsc{Agda}.) The structure of the term is otherwise preserved. The operations of the applicative functor are used when constructing the new term. The function{~}\texttt{extEnv} allows carrying the environment under a binding.% {\nopagebreak } % %code: % %comment: module TraverseTm {E} (E-app : Applicative E) % {Env} (trKit : TrKit Env (E ∘ Tm)) where % open Applicative E-app % open TrKit trKit % % trTm : ∀ {α β} → Env α β → (Tm α → E (Tm β)) % trTm Δ (V x) = trName Δ x % trTm Δ (t · u) = pure _·_ ⊛ trTm Δ t ⊛ trTm Δ u % trTm Δ (ƛ b t) = pure (ƛ _) ⊛ trTm (extEnv b Δ) t % trTm Δ (Let b t u) = pure (Let _) ⊛ trTm Δ t % ⊛ trTm (extEnv b Δ) u % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}TraverseTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}E-app\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9em}}\makebox[1.22ex][l]{\{{}}Env\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trKit\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}Tm\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}open\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E-app{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}open\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}trKit{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}trTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}trName\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extEnv\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{18em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}trTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extEnv\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: trTm' It is convenient to also define a specialized version of{~}\texttt{trTm}, which accepts a {``}name-to-name{''} kit and preserves the data constructor{~}\texttt{V}.% {\nopagebreak } % %code: % %comment: open TraverseTm %trTm′ : ∀ {E} (E-app : Applicative E) % {Env} (trKit : TrKit Env (E ∘ Name)) % {α β} → Env α β → (Tm α → E (Tm β)) %trTm′ E-app trKit % = trTm E-app (mapKit id (Applicative._<$>_ E-app V) trKit) % ~\\~\vphantom{$\{$}\texttt{open\mbox{\hspace{0.50em}}TraverseTm{\nopagebreak \newline% }\vphantom{$\{$}trTm\ensuremath{^{\prime}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}E-app\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}\makebox[1.22ex][l]{\{{}}Env\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trKit\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}TrKit\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}Name\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}trTm\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}trKit{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}mapKit\mbox{\hspace{0.50em}}id\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Applicative.\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\textless{}}\${}\makebox[1.22ex][c]{\textgreater{}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}V\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}trKit\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsubsection{Reusing the traversal\label{fruitS}} % %paragraphName: reusing the traversal We can now collect the fruit of our work, by combining the reusable traversal with various kits. For the sake of simplicity, we demonstrate this at type{~}\texttt{Tm}. In the actual implementation{~}\cite{nompa-pouillard-11}, we further abstract over{~}\texttt{Tm} and{~}\texttt{trTm} by defining a sequence of parameterized modules.% % %paragraphName: coerceTm We now revisit the definition of{~}\texttt{coerceTm}. Our earlier definition (section{~}\ref{coercingKitS}) can be replaced with a more concise one{:} all we have to do is instantiate the generic traversal{~}\texttt{trTm\ensuremath{^{\prime}}}\index{Code!\texttt{trTm\ensuremath{^{\prime}}}} with the identity applicative functor (which denotes the absence of side effects) and with the coercing kit.% {\nopagebreak } % %code: % %comment: -- The identity applicative functor %id-app : Applicative id %id-app = {! definition omitted !} % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}The\mbox{\hspace{0.50em}}identity\mbox{\hspace{0.50em}}applicative\mbox{\hspace{0.50em}}functor{\nopagebreak \newline% }\vphantom{$\{$}id-app\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}id{\nopagebreak \newline% }\vphantom{$\{$}id-app\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}definition\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: coerceTm : ∀ {α β} → α ⊆ β → α →™ β %coerceTm = trTm′ id-app coerceKit % \vphantom{$\{$}\texttt{coerceTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}coerceTm\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}id-app\mbox{\hspace{0.50em}}coerceKit{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: coerceTm can be erased We would like to think of{~}\texttt{coerceTm} as a coercion, that is, an identity function. One can informally check that if worlds and proofs of membership in a world were erased, then{~}\texttt{coerceTm} would indeed boil down to the identity function, which means that applications of{~}\texttt{coerceTm} could be optimized away. However, formally studying world erasure, as well as persuading \textsc{Agda} to perform this erasure, are left for future work.% % %paragraphName: renameTm To obtain a function that renames a term, we instantiate the generic traversal{~}\texttt{trTm\ensuremath{^{\prime}}}\index{Code!\texttt{trTm\ensuremath{^{\prime}}}} with the identity applicative functor and with the total renaming kit.% {\nopagebreak } % %code: % %comment: renameTm : ∀ {α β} → Supply β → (α →ᴺ β) → (α →™ β) %renameTm s f = trTm′ id-app renameKit (f , s) % ~\\~\vphantom{$\{$}\texttt{renameTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}renameTm\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}id-app\mbox{\hspace{0.50em}}renameKit\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}s\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: renameTmA,renameTm? To obtain a function that renames a term while allowing for failure, we instantiate it with the applicative functor{~}\texttt{Maybe} and with the partial renaming kit.% {\nopagebreak } % %code: % %comment: renameTmA : ∀ {E} → Applicative E → % ∀ {α β} → Supply β → (Name α → E (Name β)) % → (Tm α → E (Tm β)) %renameTmA E-app s f = trTm′ E-app (renameAKit E-app) (f , s) % ~\\~\vphantom{$\{$}\texttt{renameTmA\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{16em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}renameTmA\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}renameAKit\mbox{\hspace{0.50em}}E-app\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}s\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: renameTm? : ∀ {α β} → Supply β → (Name α →? Name β) % → (Tm α →? Tm β) %renameTm? = renameTmA Maybe.applicative % \vphantom{$\{$}\texttt{renameTm?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{16em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{1.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}renameTm?\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTmA\mbox{\hspace{0.50em}}Maybe.applicative{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: exportTm? Obtaining a function that exports a term is now just a matter of instantiating{~}\texttt{renameTm?}\index{Code!\texttt{renameTm?}} with the partial function{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}.% {\nopagebreak } % %code: % %comment: exportTm? : ∀ {b α} → Supply α → Tm (b ◅ α) →? Tm α %exportTm? s = renameTm? s exportᴺ? % ~\\~\vphantom{$\{$}\texttt{exportTm?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}exportTm?\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm?\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}export\makebox[0.61ex][l]{\textsuperscript{N}}?{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: closeTm? Another useful special case of{~}\texttt{renameTm?} is{~}\texttt{closeTm?}\index{Code!\texttt{closeTm?}}. This function takes a term in any world and checks if the term is closed. If so, the same term is returned, and its type is refined to the empty world. Otherwise, the function fails by returning{~}\texttt{nothing}{:}% {\nopagebreak } % %code: % %comment: closeTm? : ∀ {α} → Tm α →? Tm ø %closeTm? = renameTm? zeroˢ (const nothing) % ~\\~\vphantom{$\{$}\texttt{closeTm?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}closeTm?\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm?\mbox{\hspace{0.50em}}zero\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}const\mbox{\hspace{0.50em}}nothing\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: substTm Finally, in order to define capture-avoiding substitution, we use the substitution kit with arguments{~}\texttt{V} (which means that free variables are mapped to themselves) and{~}\texttt{coerceTm}\index{Code!\texttt{coerceTm}}.% {\nopagebreak } % %code: % %comment: substTm : ∀ {α β} → Supply β → (Name α → Tm β) → (α →™ β) %substTm (s , s#) f = trTm id-app (substKit V coerceTm) (f , s, s#) % ~\\~\vphantom{$\{$}\texttt{substTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}substTm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}s\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}s\#{}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\mbox{\hspace{0.50em}}id-app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}substKit\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}coerceTm\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}s,\mbox{\hspace{0.50em}}s\#{}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: β-red To illustrate the use of{~}\texttt{substTm}\index{Code!\texttt{substTm}}, here is a simple function, baptised{~}\texttt{\makebox[1.22ex][c]{$ \beta $}-red}\index{Code!\texttt{\makebox[1.22ex][c]{$ \beta $}-red}}, which performs a $ \beta $-reduction when a $ \beta $-redex appears at the root of its argument. The function{~}\texttt{exportWith\makebox[1.22ex][c]{{~}}a\makebox[1.22ex][c]{{~}}V} maps{~}\texttt{a} to{~}\texttt{b} and maps{~}\texttt{x} to{~}\texttt{V\makebox[1.22ex][c]{{~}}x} when{~}\texttt{x\makebox[1.22ex][c]{{~}}\ensuremath{\npnotequiv}\makebox[1.22ex][c]{{~}}b}.% {\nopagebreak } % %code: % %comment: β-red : ∀ {α} → Supply α → Tm α → Tm α %β-red s (ƛ b f · a) = substTm s (exportWith a V) f %β-red _ t = t % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{$ \beta $}-red\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \beta $}-red\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}a\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}substTm\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}exportWith\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}V\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}f{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \beta $}-red\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}t\mbox{\hspace{5.50em}}{\char `\=}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Building any $ \lambda $-term\label{nominalConv}} % %paragraphName: intro One way to argue that every $ \lambda $-term can be represented using our type{~}\texttt{Tm} is to define a conversion function from another type for $ \lambda $-terms to the type{~}\texttt{Tm}. We do so by choosing the {``}bare nominal{''} type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{A}}} of section{~}\ref{bareNominal} as the source language.% % %paragraphName: the kit The process is very close to the combination of a specific renaming kit and a specific traversal function. The kit is specific because the source names are of type{~}\texttt{Atom} and not{~}\texttt{Name}. The traversal function is specific because the source and target types are not the same and because we fix the identity functor for simplicity.% % %paragraphName: the environment type First, we introduce the type of environments. An environment holds a mapping from free atoms to free names and a name supply{:}% {\nopagebreak } % %code: % %comment: module Conv-Tmᴬ→Tm where % record Env α : Set where % constructor _,_ % field % trAtom : Atom → Name α % supply : Supply α % open Supply supply public % open Env % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}Conv-Tm\makebox[0.61ex][l]{\textsuperscript{A}}$ \rightarrow $Tm\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}record\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}constructor\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}field{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}trAtom\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Atom\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}supply\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}open\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}supply\mbox{\hspace{0.50em}}public{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}open\mbox{\hspace{0.50em}}Env{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: environment extension Then, we define how an environment is extended. This is similar to what we did for the renaming kit{:}% {\nopagebreak } % %code: % %comment: extEnv : ∀ {α} → Atom → (Δ : Env α) → Env (seedᴮ Δ ◅ α) % extEnv bᴬ Δ = trᴺ , sucˢ (supply Δ) % where trᴺ = λ xᴬ → if bᴬ ==ᴬ xᴬ % then nameᴮ (seedᴮ Δ) % else coerceᴺ (⊆-# (seed# Δ)) (trAtom Δ xᴬ) % ~\\~\vphantom{$\{$}\texttt{\mbox{\hspace{1em}}extEnv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Atom\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}extEnv\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}tr\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}suc\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}where\mbox{\hspace{0.50em}}tr\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}$ \lambda $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}if\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\textsuperscript{A}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}then\mbox{\hspace{0.50em}}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}seed\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{12em}}else\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}seed\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trAtom\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\textsuperscript{A}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: the traversal It is then straightforward to define the conversion function,{~}\texttt{conv}\index{Code!\texttt{conv}}. We use{~}\texttt{trAtom}\index{Code!\texttt{trAtom}} at variable occurrences and{~}\texttt{extEnv}\index{Code!\texttt{extEnv}} when crossing a binding.% {\nopagebreak } % %code: % %comment: conv : ∀ {α} → Env α → Tmᴬ → Tm α % conv Δ (V x) = V (trAtom Δ x) % conv Δ (ƛ b t) = ƛ _ (conv (extEnv b Δ) t) % conv Δ (t · u) = conv Δ t · conv Δ u % conv Δ (Let b t u) = Let _ (conv Δ t) (conv (extEnv b Δ) u) % ~\\~\vphantom{$\{$}\texttt{\mbox{\hspace{1em}}conv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trAtom\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extEnv\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}Let\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}conv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}extEnv\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Delta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: empty environment In order to use the function{~}\texttt{conv}, one must provide an environment, that is, a mapping of (all) atoms to names in the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} together with a name supply for{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. Of course, this is possible only if{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} is a non-empty world. For instance, the following environment, whose action maps all atoms to the name{~}\texttt{0\makebox[1.22ex][c]{{~}}\makebox[0.61ex][l]{\textsuperscript{N}}} and whose name supply begins at{~}\texttt{1\makebox[1.22ex][c]{{~}}\makebox[0.61ex][l]{\textsuperscript{N}}}, is an environment for the singleton world{~}\texttt{0\makebox[1.22ex][c]{{~}}\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}}.% {\nopagebreak } % %code: % %comment: emptyEnv : Env (0 ᴮ ◅ ø) % emptyEnv = const (0 ᴺ) , sucˢ zeroˢ % ~\\~\vphantom{$\{$}\texttt{\mbox{\hspace{1em}}emptyEnv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Env\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}emptyEnv\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}const\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}suc\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}zero\makebox[0.61ex][l]{\textsuperscript{s}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: closed terms By post-composing the conversion function \texttt{conv\makebox[1.22ex][c]{{~}}emptyEnv} with the test for closedness{~}\texttt{closeTm?}, we obtain a function that converts a closed {``}bare nominal{''} term of type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{A}}} to a term of type{~}\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}}. This function fails if its argument is not a closed term.% {\nopagebreak } % %code: % %comment: convø? : Tmᴬ →? Tm ø % convø? = closeTm? ∘ conv emptyEnv % ~\\~\vphantom{$\{$}\texttt{\mbox{\hspace{1em}}conv\makebox[1.22ex][c]{$ \emptyset $}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{A}}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}conv\makebox[1.22ex][c]{$ \emptyset $}?\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}closeTm?\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}conv\mbox{\hspace{0.50em}}emptyEnv{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Towards elaborate uses of worlds\label{elaborateS}} % %paragraphName: elaborate uses The type{~}\texttt{Tm} is just one basic example of an algebraic data type that involves names and binders. Let us briefly present a few algebraic data type definitions that make more advanced use of worlds.% \paragraph{Contexts} % %paragraphName: One hole contexts (C) Consider a type{~}\texttt{C} of one-hole contexts associated with{~}\texttt{Tm}. The type{~}\texttt{C} is indexed with two worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} and{~}\texttt{\makebox[1.22ex][c]{$ \beta $}}, which respectively play the role of an {``}outer world{''} and an {``}inner world{''}. The idea is, plugging a term of type{~}\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}} into the hole of a context of type{~}\texttt{C\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}} produces a term of type{~}\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. The definition of the type{~}\texttt{C} is as follows{:}% {\nopagebreak } % %code: % %comment: data C α : World → Set where % Hole : C α α % _·₁_ : ∀ {β} → C α β → Tm α → C α β % _·₂_ : ∀ {β} → Tm α → C α β → C α β % ƛ : ∀ {β} b → C (b ◅ α) β → C α β % Let₁ : ∀ {β} b → C α β % → Tm (b ◅ α) → C α β % Let₂ : ∀ {β} b → Tm α % → C (b ◅ α) β → C α β % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Hole\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: contexts bind names Contexts bind names{:} the hole can appear under one or several binders. This is why, in general, a context has distinct outer and inner worlds. A context contains a list of binders that {``}connects{''} the outer and inner worlds{:} these binders are carried by the constructors{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}} and{~}\texttt{Let\makebox[0.61ex][l]{$ _{{2}} $}}.% % %paragraphName: CTm A context and a term can be paired to produce a term-in-context. This can be viewed as a user-defined binding construct{:} the names introduced by the context are in scope in the term. In fact, a one-hole context for a data structure that involves binders is exactly what de Bruijn calls a {``}telescope{''}{~}\shortcite{de-bruijn-91}. A telescope is a first-class object that has binding power, that is, it binds zero or more names.% {\nopagebreak } % %code: % %comment: CTm : World → Set %CTm α = ∃[ β ](C α β × Tm β) % ~\\~\vphantom{$\{$}\texttt{CTm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}CTm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}$ \exists ${[}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{]}\makebox[1.22ex][l]{$ {(} $}C\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \times $}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: plug It is straightforward to define a function{~}\texttt{plug}\index{Code!\texttt{plug}} from{~}\texttt{CTm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} to{~}\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}, which accepts a pair of a context and a term and plugs the latter into the former. Conversely, one can define a family of focusing functions of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{CTm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} that split a term into a pair of a context and a term. There are several such functions, according to where one wishes to focus.% % %paragraphName: more The contexts presented here are {``}ordinary{''} contexts{:} the root of the context is the root of the term, and as one goes down into the context, one goes down into the term. Of course, since a context is just a list, it is possible to hold it from the other end. A context that is {``}inside-out{''} is known as a {``}zipper{''}{~}\cite{huet-zipper-97,mcbride-derivative}. Our system can express zippers, as well as the list reversal functions that allow transforming a telescope into a zipper and vice-versa. Unfortunately, describing this in detail would take us a little too far, so we leave this for another occasion.% \paragraph{Multiple sorts of names} % %paragraphName: System F Some object languages have multiple sorts of names. For instance, in Girard and Reynolds{'} System{~}$ {F} $, there are term variables, which occur in terms, and type variables, which occur in types and in terms. Thus, it is natural to index object-level types with one world (which tells which type variables are in scope) and to index object-level terms with two worlds (one of which concerns type variables, the other of which concerns term variables).% {\nopagebreak } % %code: % %comment: module SysF where % infixr 5 _⇒_ % data Ty α : Set where % V : (x : Name α) → Ty α % _⇒_ : (σ τ : Ty α) → Ty α % `∀` : ∀ b (τ : Ty (b ◅ α)) → Ty α % % data Tm α γ : Set where % V : ∀ (x : Name α) → Tm α γ % _·_ : ∀ (t u : Tm α γ) → Tm α γ % ƛ : ∀ b (τ : Ty γ) % (t : Tm (b ◅ α) γ) → Tm α γ % _·τ_ : ∀ (t : Tm α γ) (τ : Ty γ) → Tm α γ % Λ : ∀ b (t : Tm α (b ◅ γ)) → Tm α γ % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}SysF\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}infixr\mbox{\hspace{0.50em}}5\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}$ \Rightarrow $\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}data\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}V\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{5em}}$ \rightarrow $\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}$ \Rightarrow $\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \sigma $\mbox{\hspace{0.50em}}$ \tau $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{5em}}$ \rightarrow $\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}{`}\makebox[1.22ex][c]{$ \forall $}{`}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \tau $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}data\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}V\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{6em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{5em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \tau $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{8em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}$ \tau $\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \tau $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ty\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \Lambda $}\mbox{\hspace{1em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \gamma $}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Advanced example{:} normalization by evaluation\label{nbeS}} % %paragraphName: challenge As an advanced example, we show how to express a normalization by evaluation algorithm in our system. This algorithm has been previously used as a benchmark by several researchers{~}\cite{shinwell-03,pitts-06,licata-harper-09,cave-12}. The challenge lies in the way in which the algorithm mixes computational functions, name abstractions, and fresh name generation.% % %paragraphName: syntactic and semantic terms The object language of interest is again the pure $ \lambda $-calculus. The algorithm exploits two different representations of object-level terms, which are respectively known as \emph{syntactic} and \emph{semantic} representations. Because these representations differ only in their treatment of name abstractions, they can be given a common definition, which is parameterized over the representation of name abstractions{:}% {\nopagebreak } % %code: % %comment: module M (Abs : (World → Set) → World → Set) where % data T α : Set where % V : Name α → T α % ƛ : Abs T α → T α % _·_ : T α → T α → T α % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}M\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Abs\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}data\mbox{\hspace{0.50em}}T\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}V\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{2.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}T\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}Abs\mbox{\hspace{0.50em}}T\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{2em}}$ \rightarrow $\mbox{\hspace{0.50em}}T\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}T\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}T\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}T\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Abs The parameter{~}\texttt{Abs} has kind{~}\texttt{\makebox[1.22ex][l]{$ {(} $}World\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Set\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}World\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Set\makebox[1.22ex][r]{$ {)} $}}{:} it is an indexed-type transformer.% % %paragraphName: SynAbsᴺ In order to obtain the syntactic representation, we instantiate{~}\texttt{Abs} with the nominal abstractions that we have used everywhere so far{:} an abstraction is a package of a binder and of a term that inhabits an extended world. This yields the type{~}\texttt{Term} of syntactic terms.\index{Code!\texttt{SynAbs\makebox[0.61ex][l]{\textsuperscript{N}}}}% {\nopagebreak } % %code: % %comment: SynAbsᴺ : (World → Set) → World → Set %SynAbsᴺ F α = ∃[ b ](F (b ◅ α)) % %open M SynAbsᴺ renaming (T to Term) % ~\\~\vphantom{$\{$}\texttt{SynAbs\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}SynAbs\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}$ \exists ${[}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}{]}\makebox[1.22ex][l]{$ {(} $}F\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}open\mbox{\hspace{0.50em}}M\mbox{\hspace{0.50em}}SynAbs\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}renaming\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}T\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}Term\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: SemAbs In order to obtain the semantic representation, we instantiate{~}\texttt{Abs} with a different notion of abstraction, in the style of higher-order abstract syntax{:} an abstraction is a computational function, which substitutes a term for the bound name of the abstraction\index{Code!\texttt{SemAbs}}. This yields the type{~}\texttt{Sem}\index{Code!\texttt{Sem}} of semantic terms.% {\nopagebreak } % %code: % %comment: SemAbs : (World → Set) → World → Set %SemAbs F α = ∀ {β} → α ⊆ β → F β → F β % %open M SemAbs renaming (T to Sem) % ~\\~\vphantom{$\{$}\texttt{SemAbs\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}SemAbs\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}F\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}open\mbox{\hspace{0.50em}}M\mbox{\hspace{0.50em}}SemAbs\mbox{\hspace{0.50em}}renaming\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}T\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}Sem\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: termination \texttt{Sem} is not an inductive data type. Fortunately, with the{~}\texttt{--no-positivity-check} flag, \textsc{Agda} accepts this type definition, at the cost of breaking strong normalization. (To minimize risk, we isolate this code in a module where this flag is activated.) Naturally, because untyped $ \lambda $-calculus is not terminating, one cannot expect to be able to implement a terminating normalization procedure.% % %paragraphName: bounded polymorphism Our semantic name abstractions involve bounded polymorphism in a world{:} we define \texttt{SemAbs\makebox[1.22ex][c]{{~}}F\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} as{~}{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{F\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{F\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}, as opposed to the more na\"{i}ve{~}\texttt{F\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{F\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. This provides a more accurate and more flexible description of the behavior of substitution. Indeed, when instantiating an abstraction{~}\texttt{t} with some term{~}\texttt{u}, it makes perfect sense for{~}\texttt{u} to inhabit a larger world than{~}\texttt{t}, that is, for{~}\texttt{u} to refer to certain names that are fresh for{~}\texttt{t}. The result of the substitution then inhabits the same world as{~}\texttt{u}{:} that is, it potentially refers to these fresh names, in addition to all of the names that occurred free in the abstraction{~}\texttt{t}.% % %paragraphName: Sem covariant The types{~}\texttt{SemAbs}\index{Code!\texttt{SemAbs}} and{~}\texttt{Sem} are covariant with respect to the parameter{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. This would not be the case had we adopted the na\"{i}ve definition of{~}\texttt{SemAbs}. In other words, it is possible to define a {``}coerce{''} operation for semantic terms{:}% {\nopagebreak } % %code: % %comment: coerceSem : ∀ {α β} → α ⊆ β → (Sem α → Sem β) %coerceSem pf (V a) = V (coerceᴺ pf a) %coerceSem pf (ƛ f) = ƛ (λ pf′ v → f (⊆-trans pf pf′) v) %coerceSem pf (t · u) = coerceSem pf t · coerceSem pf u % ~\\~\vphantom{$\{$}\texttt{coerceSem\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}coerceSem\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}a\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2em}}{\char `\=}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}a\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}coerceSem\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}pf\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-trans\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}pf\ensuremath{^{\prime}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}v\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}coerceSem\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}coerceSem\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}coerceSem\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: no rec call on ƛ At a semantic abstraction, no recursive call is performed, because the body of the abstraction is opaque{:} it is a computational function. Instead, we exploit the transitivity of world inclusion and build a new semantic abstraction that inhabits the desired world. Like{~}\texttt{coerceTm} (section{~}\ref{fruitS}), \texttt{coerceSem} is a {``}coercion{''}, in the sense that, if worlds and proofs of membership in a world were erased, \texttt{coerceSem} would boil down to the identity function.% % %paragraphName: funEnv The normalization by evaluation algorithm makes use of environments. Here, environments are functions from names to semantic terms. The function{~}\texttt{\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\makebox[1.22ex][c]{\_{}}}} extends such an environment{:}% {\nopagebreak } % %code: % %comment: EvalEnv : (α β : World) → Set %EvalEnv α β = Name α → Sem β %-- α is the inner world %-- β is the outer world % %_,_↦_ : ∀ {α β} (Γ : EvalEnv α β) b → Sem β → EvalEnv (b ◅ α) β %_,_↦_ Γ b v = exportWith v Γ %-- meaning: b ↦ v %-- x ↦ Γ x % ~\\~\vphantom{$\{$}\texttt{EvalEnv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}EvalEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}inner\mbox{\hspace{0.50em}}world{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}outer\mbox{\hspace{0.50em}}world{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}EvalEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}EvalEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}exportWith\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}meaning{:}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\mbox{\hspace{0.50em}}v{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{5em}}x\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: EvalEnv/coerceEnv An environment, of type{~}\texttt{EvalEnv\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}} maps a name of type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} to a semantic term that lies outside the scope of the environment, that is, a semantic term of type{~}\texttt{Sem\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}. The type{~}\texttt{EvalEnv\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}} is covariant in its destination world, as witnessed by the following coercion function{:}% {\nopagebreak } % %code: % %comment: coerceEnv : ∀{α β₁ β₂}→ β₁ ⊆ β₂ → EvalEnv α β₁ → EvalEnv α β₂ %coerceEnv pf Γ = coerceSem pf ∘ Γ % ~\\~\vphantom{$\{$}\texttt{coerceEnv\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}EvalEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}EvalEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}coerceEnv\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}coerceSem\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: eval The first part of the normalization by evaluation algorithm is a function{~}\texttt{eval}\index{Code!\texttt{eval}} that evaluates a syntactic term within an environment to produce a semantic term. When evaluating a $ \lambda $-abstraction, we build a semantic abstraction, which encapsulates a recursive call to{~}\texttt{eval}. The bounded polymorphism required by the definition of semantic abstractions forces us to coerce the environment{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} via{~}\texttt{coerceEnv}\index{Code!\texttt{coerceEnv}}.% {\nopagebreak } % %code: % %comment: eval : ∀ {α β} → EvalEnv α β → Term α → Sem β %eval Γ (ƛ (a , t)) % = ƛ (λ pf v → eval (coerceEnv pf Γ , a ↦ v) t) %eval Γ (V x) = Γ x %eval Γ (t · u) = app (eval Γ t) (eval Γ u) where % app : ∀ {α} → Sem α → Sem α → Sem α % app (ƛ f) v = f ⊆-refl v % app n v = n · v % ~\\~\vphantom{$\{$}\texttt{eval\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}EvalEnv\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Term\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}eval\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}a\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}eval\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerceEnv\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\mapsto}}\mbox{\hspace{0.50em}}v\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}eval\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}eval\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}eval\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}eval\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}app\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}v\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-refl\mbox{\hspace{0.50em}}v{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}app\mbox{\hspace{0.50em}}n\mbox{\hspace{3em}}v\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}v{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: reify The second part of the algorithm reifies a semantic term back into a syntactic term. When reifying a semantic abstraction, we build a syntactic abstraction. This requires generating a fresh name, and leads us to parameterizing{~}\texttt{reify}\index{Code!\texttt{reify}} with a supply of fresh names.% {\nopagebreak } % %code: % %comment: reify : ∀ {α} → Supply α → Sem α → Term α %reify s (V a) = V a %reify s (n · v) = reify s n · reify s v %reify (sᴮ , s#) (ƛ f) = % ƛ (sᴮ , reify (sucˢ (sᴮ , s#)) (f (⊆-# s#) (V (nameᴮ sᴮ)))) % ~\\~\vphantom{$\{$}\texttt{reify\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Sem\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Term\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}reify\mbox{\hspace{0.50em}}s\mbox{\hspace{2.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{1em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}a\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}a{\nopagebreak \newline% }\vphantom{$\{$}reify\mbox{\hspace{0.50em}}s\mbox{\hspace{2.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{1em}}\makebox[1.22ex][l]{$ {(} $}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}v\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}reify\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}reify\mbox{\hspace{0.50em}}s\mbox{\hspace{0.50em}}v{\nopagebreak \newline% }\vphantom{$\{$}reify\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}s\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}s\#{}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}s\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}reify\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}s\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}s\#{}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-\#{}\mbox{\hspace{0.50em}}s\#{}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}s\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: nf The constructor{~}\texttt{V} has type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Sem\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. Hence, it is a valid initial environment of type{~}\texttt{EvalEnv\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. Evaluation under this initial environment, followed with reification, yields a normalization algorithm. This algorithm works with open terms{:} its argument, as well as its result, are terms in an arbitrary world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, provided we have a name supply for the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}.% {\nopagebreak } % %code: % %comment: nf : ∀ {α} → Supply α → Term α → Term α %nf supply = reify supply ∘ eval V % ~\\~\vphantom{$\{$}\texttt{nf\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Supply\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Term\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Term\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}nf\mbox{\hspace{0.50em}}supply\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}reify\mbox{\hspace{0.50em}}supply\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}eval\mbox{\hspace{0.50em}}V{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ex In particular,{~}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{s}}} is a name supply for the empty world, so we can normalize closed terms. Here is an example of the normalization of a closed term{:}% {\nopagebreak } % %code: % %comment: idᵀ : Term ø %idᵀ = ƛ (0 ᴮ , V (0 ᴺ)) % %test-nf : nf zeroˢ ((idᵀ · (idᵀ · idᵀ)) · idᵀ) ≡ idᵀ %test-nf = refl % ~\\~\vphantom{$\{$}\texttt{id\makebox[0.61ex][l]{\textsuperscript{T}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Term\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}id\makebox[0.61ex][l]{\textsuperscript{T}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}test-nf\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}nf\mbox{\hspace{0.50em}}zero\makebox[0.61ex][l]{\textsuperscript{s}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}id\makebox[0.61ex][l]{\textsuperscript{T}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}id\makebox[0.61ex][l]{\textsuperscript{T}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}id\makebox[0.61ex][l]{\textsuperscript{T}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}id\makebox[0.61ex][l]{\textsuperscript{T}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}id\makebox[0.61ex][l]{\textsuperscript{T}}{\nopagebreak \newline% }\vphantom{$\{$}test-nf\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}refl{\nopagebreak \newline% }\vphantom{$\{$}}% \section{The \textsc{NomPa} implementation (nominal fragment)\label{nompaImplem}} % %paragraphName: intro The implementation of our library (of which only the nominal fragment has been presented so far) is not surprising. Most of the code consists of types and proofs. Although we now present some of the internal details of our library, we emphasize that none of these definitions are meant to be known to or used by the client.% % %paragraphName: World,ø,_∈_ Worlds are defined first. A world is represented by a list of Booleans. An integer atom{~}n is deemed a member of the world if and only if the{~}$ {n} $\textsuperscript{th} element of the list is{~}\texttt{true}. More formally, the meaning of a world is defined by the following membership predicate.% {\nopagebreak } % %code: % %comment: World : Set %World = List Bool % %ø : World %ø = [] % ~\\~\vphantom{$\{$}\texttt{World\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}World\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: _∈_ : ℕ → World → Set %_ ∈ [] = ⊥ %zero ∈ (false ∷ _) = ⊥ %zero ∈ (true ∷ _) = ⊤ %suc n ∈ (_ ∷ xs) = n ∈ xs % \vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \in $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{3em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{6em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}{\nopagebreak \newline% }\vphantom{$\{$}zero\mbox{\hspace{1.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}false\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}{\nopagebreak \newline% }\vphantom{$\{$}zero\mbox{\hspace{1.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}true\mbox{\hspace{1em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \top $}{\nopagebreak \newline% }\vphantom{$\{$}suc\mbox{\hspace{0.50em}}n\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{2.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}xs\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}xs{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: choice of representation of worlds The choice of a list of Booleans to represent a world was guided by two facts. First, operations over worlds are defined by structural induction. This makes type-level computation easier, and becomes especially important when we introduce support for de Bruijn indices (section{~}\ref{napaS}). Second, because elements are ordered, modulo trailing occurrences of{~}\texttt{false}, two equivalent sets are represented in the same way.% % %paragraphName: erasing worlds Worlds are meant to be computationally irrelevant. This means that, prior to running a program, it should be possible in principle to erase worlds as well as proofs of membership in a world, proofs of world inclusion, and proofs of freshness. A program in which worlds have been erased should behave in the same manner as the original program in which worlds are present, but opaque. There are two reasons why we wish to have such an erasure property{:} first, it means that there is a clear {``}phase distinction{''} between the code that we wish to run and the world annotations that explain why this code makes sense; second, this guarantees that world annotations incur no performance penalty.% % %paragraphName: erasing worlds, continued Although we do not formally demonstrate that it is possible to erase worlds, the library is designed with this goal in mind. In particular, we are careful \emph{not} to include in the library any operation that constructs a non-erasable result out of an erasable argument. An example of this would be an operation that accepts a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} and produces a binder{~}\texttt{b} that is fresh for \texttt{\makebox[1.22ex][c]{$ \alpha $}}. To compensate for the lack of such an operation, the client of the library must work with explicit name supplies where required. It might be possible to add this operation to the library (somewhat amazingly, it seems that the soundness proof in section{~}\ref{nompaSoundnessS} would support it) and to implement it, after erasure, as an effectful {``}global gensym{''} operation. We leave this idea for future work.% % %paragraphName: worlds are not irrelevant to Agda A notion of irrelevance has recently been introduced in \textsc{Agda}. The irrelevant function space is noted \texttt{.\makebox[1.22ex][l]{$ {(} $}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B}. The value of an irrelevant argument not only cannot influence the result of a computation, but also cannot influence the type-checking process{:} any two irrelevant values of the same type are considered equal. Hence, irrelevance can be used only in situations where the only thing that matters is the existence of a value of a certain type. In our setting, worlds cannot be considered irrelevant. The following example shows that considering an arbitrary world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} as equal to the empty world leads to nonsense{:}% {\nopagebreak } % %code: % %comment: module Worlds-should-be-erased-but-are-relevant % (World : Set) -- A type for worlds % (ø : World) -- An empty world % (Name : .World → Set) -- Names are made world irrelevant % (¬Nameø : ¬(Name ø)) -- No name inhabits ø % .(α : World) -- An irrelevant world % (x : Name α) -- A name %where % bot : ⊥ -- ...and that's the end of the world % bot = ¬Nameø x % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}Worlds-should-be-erased-but-are-relevant{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][l]{$ {(} $}World\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{5.50em}}--\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}type\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}worlds{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{6.50em}}--\mbox{\hspace{0.50em}}An\mbox{\hspace{0.50em}}empty\mbox{\hspace{0.50em}}world{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}.World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}--\mbox{\hspace{0.50em}}Names\mbox{\hspace{0.50em}}are\mbox{\hspace{0.50em}}made\mbox{\hspace{0.50em}}world\mbox{\hspace{0.50em}}irrelevant{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}--\mbox{\hspace{0.50em}}No\mbox{\hspace{0.50em}}name\mbox{\hspace{0.50em}}inhabits\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{0.50em}}.\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{6.50em}}--\mbox{\hspace{0.50em}}An\mbox{\hspace{0.50em}}irrelevant\mbox{\hspace{0.50em}}world{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{6em}}--\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}name{\nopagebreak \newline% }\vphantom{$\{$}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}bot\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}\mbox{\hspace{8.50em}}--\mbox{\hspace{0.50em}}...and\mbox{\hspace{0.50em}}that{'}s\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}end\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}world{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}bot\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: witness irrelevance One might however be able to apply \textsc{Agda} irrelevance to proof terms, such as world membership witnesses, fresh-for witnesses, and maybe inclusion witnesses as well. Our experiments were successful as far as the implementation is concerned, but led to trouble in the proofs. We leave this aspect to future work.% % %paragraphName: Binder,zeroᴮ,sucᴮ,_◅_ Binders are represented by natural numbers. The operation{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}}} defines how to extend a world with a binder. Given a binder{~}\texttt{n} and a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, it updates the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} with the value{~}\texttt{true} at index{~}\texttt{n}.% {\nopagebreak } % %code: % %comment: Binder : Set %Binder = ℕ % %zeroᴮ : Binder %zeroᴮ = zero % %sucᴮ : Binder → Binder %sucᴮ = suc % ~\\~\vphantom{$\{$}\texttt{Binder\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}Binder\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}zero\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}zero\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}zero{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}suc\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}suc\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}suc{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: _◅_ : Binder → World → World %zero ◅ [] = true ∷ [] %suc n ◅ [] = false ∷ n ◅ [] %zero ◅ (_ ∷ α) = true ∷ α %suc n ◅ (b ∷ α) = b ∷ n ◅ α % %infixr 5 _◅_ % \vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}zero\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{3em}}{\char `\=}\mbox{\hspace{0.50em}}true\mbox{\hspace{1em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}suc\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{3em}}{\char `\=}\mbox{\hspace{0.50em}}false\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}zero\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}true\mbox{\hspace{1em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}suc\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}b\mbox{\hspace{2.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}infixr\mbox{\hspace{0.50em}}5\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ◅-sem The proof that{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}}} has the intended set-theoretic semantics is offered by the following lemma{:}% {\nopagebreak } % %code: % %comment: ◅-sem : ∀ α x y → (x ∈ y ◅ α) ≡ (if x ==ℕ y then ⊤ else x ∈ α) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\ensuremath{\triangleleft}}-sem\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}if\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}then\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \top $}\mbox{\hspace{0.50em}}else\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Name A name of type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} is a pair of a binder (that is, a number) and a proof that this binder is a member of the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. In \textsc{Agda}, we use a record{:}% {\nopagebreak } % %code: % %comment: record Name α : Set where % constructor _,_ % field % binderᴺ : Binder % b∈α : binderᴺ ∈ α %infixr 4 _,_ %open Name public % ~\\~\vphantom{$\{$}\texttt{record\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}constructor\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}field{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}binder\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}b\makebox[1.22ex][c]{$ \in $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{3em}}{:}\mbox{\hspace{0.50em}}binder\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}infixr\mbox{\hspace{0.50em}}4\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}open\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}public{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: nameᴮ In order to produce a name out of a binder{~}\texttt{b}, the operation{~}\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}}\index{Code!\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}}} simply packs{~}\texttt{b} together with a proof that{~}\texttt{b} is a member of the world{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. This proof is easily manually constructed.% {\nopagebreak } % %code: % %comment: nameᴮ : ∀ {α} b → Name (b ◅ α) %nameᴮ b = b , {! proof omitted !} % ~\\~\vphantom{$\{$}\texttt{name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}proof\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _==ᴺ_,exportᴺ? The equality test{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}}} and the function{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}\index{Code!\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?}} compare the integer values that underlie names and binders.% {\nopagebreak } % %code: % %comment: _==ᴺ_ : ∀ {α} (x y : Name α) → Bool %_==ᴺ_ (x , _) (y , _) = x ==ℕ y % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}y\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}y{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: exportᴺ? : ∀ {b α} → Name (b ◅ α) →? Name α %exportᴺ? {b} {α} (x , pf) = % if x ==ℕ b then nothing % else just (x , {! proof omitted !}) % \vphantom{$\{$}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}export\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}b\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}pf\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{0.50em}}if\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}then\mbox{\hspace{0.50em}}nothing{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}else\mbox{\hspace{0.50em}}just\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}proof\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⊆,coerceᴺ World inclusion is defined as set-theoretic inclusion, that is, as the preservation of membership. This is exploited in the definition of{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}}, where we need to build a proof that{~}\texttt{b} is a member of{~}\texttt{\makebox[1.22ex][c]{$ \beta $}}. Note that, after erasure, \texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}} boils down to the function that maps{~}\texttt{b} to{~}\texttt{b}, that is, the identity function.% {\nopagebreak } % %code: % %comment: infix 2 _⊆_ %_⊆_ : (α β : World) → Set %α ⊆ β = ∀ x → x ∈ α → x ∈ β % ~\\~\vphantom{$\{$}\texttt{infix\mbox{\hspace{0.50em}}2\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: coerceᴺ : ∀ {α β} → α ⊆ β → (α →ᴺ β) %coerceᴺ α⊆β (b , b∈α) = b , α⊆β b b∈α % \vphantom{$\{$}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}b\makebox[1.22ex][c]{$ \in $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}b\mbox{\hspace{0.50em}}b\makebox[1.22ex][c]{$ \in $}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⊆-refl,⊆-trans,⊆-ø,⊆-◅,⊆-# The proofs of the world inclusion rules (figure{~}\ref{nompaIfaceF}) are computationally irrelevant. We omit them here.% % %paragraphName: _#_ The remaining part is the fresh-for relation (\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}}}). To cope with the proof of{~}\texttt{suc\#{}}\index{Code!\texttt{suc\#{}}}, we give two characterizations of this relation. One is a set of syntactic rules (omitted here) and the other is semantic. These presentations are equivalent{~}\cite{nompa-pouillard-11}. The semantic version was given earlier (section{~}\ref{nameWeakeningS}){:} it states that{~}\texttt{x\makebox[1.22ex][c]{{~}}\#{}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} holds if and only if{~}\texttt{x} dominates{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, that is, \texttt{x} is strictly greater than every name{~}\texttt{y} that inhabits{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}.% {\nopagebreak } % %code: % %comment: _#_ : Binder → World → Set %x # α = ∀ y → y ∈ α → x > y % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}x\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textgreater{}}\mbox{\hspace{0.50em}}y{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: suc# This strong definition of {``}fresh-for{''} allows us to implement the operation{~}\texttt{suc\#{}} without inspecting the world{:} after erasure, \texttt{suc\#{}} is just the successor operation on natural numbers. Thus, we are able to generate fresh names in a manner that is compatible with erasure and is efficient.% \section{Soundness of \textsc{NomPa} (nominal fragment)\label{nompaSoundnessS}} % %paragraphName: why type-safety is not enough? Our library is written in \textsc{Agda}, a type-safe language. Thus, the property that {``}well-typed programs do not go wrong{''} comes for free. However, this does not quite satisfy us. Indeed, we have explained that certain operations, such as an equality test for binders, must not be provided to programmers, or it would be possible to write {``}ill-behaved{''} code. Yet, these operations are perfectly type-safe. So, type safety is not a sufficient criterion in order to determine which operations can and cannot be provided.% % %paragraphName: from our informal slogan to logical relations Earlier, we stated informally that {``}a function is well-behaved if, when applied to $ \alpha $-equivalent arguments, it produces $ \alpha $-equiv{\-}alent results{''}. This is, roughly speaking, the criterion that we are looking for{:} we would like to guarantee that every function that can be written by a client of our library is well-behaved. Of course, we must define this criterion in a more formal and more general manner. This involves defining what we mean by {``}$ \alpha $-equivalence{''}{:} we must define this relation not just at our example type{~}\texttt{Tm}, where we have a pretty clear idea of what {``}$ \alpha $-equivalence{''} means, but at every type. Similarly, we must define {``}well-behavedness{''} not just at function types, but at every type.% % %paragraphName: logical relations Fortunately, these two problems are the same. In the following, we build a logical relation, that is, a type-indexed equivalence relation. This relation gives rise to a notion of {``}$ \alpha $-equivalence{''}{:} we consider that two \textsc{Agda} expressions of type{~}\texttt{$ \tau $} are {``}$ \alpha $-equivalent{''} if and only if they are related at type{~}\texttt{$ \tau $}. It also gives rise to a notion of {``}well-behavedness{''}{:} we consider that an \textsc{Agda} expression of type{~}\texttt{$ \tau $} is {``}well-behaved{''} if and only if it is related to itself at type{~}\texttt{$ \tau $}.% % %paragraphName: logical relations are standard The construction of a logical relation for \textsc{Agda} is a standard technique{~}\cite{bernardy-10}. It is independent of our work. By relying on this technique, all we have to do is define the relation at each of the abstract types that we introduce (namely \texttt{World},{~}\texttt{Name},{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}}, etc.) and prove that each of the values that we introduce is related to itself. Each of these little proofs is independent of the others. This makes the soundness proof modular. This also facilitates the addition of new features{:} when considering the addition of a new operation, it is easy to construct the proof obligation that comes with it and to find out whether it is safe to add this operation.% % %paragraphName: plan This section is organized as follows. First, we recall the basics of logical relations and parametricity (section{~}\ref{rellogRecapS}). We give a toy example, so as to practice a bit (section{~}\ref{boolRelS}). Then, we define the logical relation at each of our abstract types, and briefly describe the proof obligations that arise about the operations of the library (section{~}\ref{nompaRel}). Finally, we discuss the meaning of the {``}free theorems{''} that arise out of this construction (section{~}\ref{tmAlphaEquivS}).% \subsection{Recap of the framework\label{rellogRecapS}} % %paragraphName: type-directed relation A relation is said to be type-indexed, or type-directed, when it is inductively defined over the structure of types. Let{~}\texttt{\makebox[1.83ex][c]{$ \mathcal{{R}} $}} be such a type-directed relation, and let{~}\texttt{$ \tau $} be a type. Then, $ \mathcal{{R}}_{\tau} $ is a relation on values of type{~}\texttt{$ \tau $}, that is, we have{~}$ \mathcal{{R}}_{\tau} $ \texttt{{:}\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Set}. Recall that{~}\texttt{Set} serves as the type of propositions in \textsc{Agda}.% % %paragraphName: logical A type-directed relation is called a {``}logical{''} relation when it relates functions in an extensional manner, that is, when two functions are related if and only if they produce related results out of related arguments. Let{~}\texttt{A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} be a relation for the arguments and \texttt{B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} a relation for results. Two functions{~}\texttt{f\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{f\makebox[0.61ex][l]{$ _{{2}} $}} are {``}logically{''} related if and only if for every pair of arguments{~}\texttt{\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{1}} $},\makebox[1.22ex][c]{{~}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}} related by{~}\texttt{A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, the results{~}\texttt{f\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}x\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{f\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}x\makebox[0.61ex][l]{$ _{{2}} $}} are related by{~}\texttt{B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}. This definition can be given in \textsc{Agda} as well{:}% {\nopagebreak } % %code: % %comment: RelatedFunctions Aᵣ Bᵣ f₁ f₂ = % ∀ {x₁ x₂} → Aᵣ x₁ x₂ % → Bᵣ (f₁ x₁) (f₂ x₂) % ~\\~\vphantom{$\{$}\texttt{RelatedFunctions\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: name conventions An expression of type \texttt{$ \tau $} {``}fits{''} a logical relation if and only if it is related to itself at type \texttt{$ \tau $}. A logical relation is \emph{universal} if every well-typed program fits this logical relation. John Reynolds defined a logical relation for the polymorphic $ \lambda $-calculus and proved that it is universal{:} this is the {``}Abstraction Theorem{''}{~}\cite{reynolds-83}. Bernardy et al.{~}\shortcite{bernardy-10} define a logical relation for every pure type system (PTS) and informally suggest how to extend it to \textsc{Agda}. While no complete mechanized definition and proof exist, we refer to this extension as the {``}\textsc{Agda} logical relation{''} and assume that it is universal. In the following, we briefly explain how the \textsc{Agda} logical relation is defined and state our assumption in a precise way.% \paragraph{The \textsc{Agda} logical relation} % %paragraphName: no universe-polymorphism In order to simplify things, the definitions that follow are not universe-poly{\-}morphic. The reader can find universe-polymorphic definitions in the full implementation{~}\cite{nompa-pouillard-11}.% % %paragraphName: the universe technique When attempting to formally define a logical relation within \textsc{Agda}, one immediately faces a difficulty{:} \textsc{Agda} does not allow structural induction over types, that is, over values of type \texttt{Set}. In order to work around this difficulty, a natural and common technique is to introduce an algebraic data type{~}\texttt{U} that represents the syntax of \textsc{Agda}{'}s types. The type{~}\texttt{U} is known as a {``}universe{''}, and its elements are known as {``}codes{''}. Then, in order to construct an explicit connection between codes and the types that they are supposed to represent, one defines a function that assigns meanings to codes. This function, called{~}\texttt{El}, has type \texttt{U\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Set}. Thus, if{~}\texttt{$ \tau $} is a code, then{~}\texttt{El\makebox[1.22ex][c]{{~}}$ \tau $} is a type, and can be thought of as {``}the elements of{~}\texttt{$ \tau $}{''}. Finally, the logical relation is defined by induction over codes. It is a function{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} that maps a code{~}\texttt{$ \tau $} to a relation over the elements of{~}\texttt{$ \tau $}. In other words, the function{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} has type \texttt{\makebox[1.22ex][l]{$ {(} $}$ \tau $\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}U\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}El\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}El\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Set}.% % %paragraphName: we do not adopt the universe technique Unfortunately, because \textsc{Agda}{'}s types involve quantification and dependent types, the algebraic data type of codes must involve some representation of names and binders. This adds a good deal of complexity to the universe technique. Perhaps ironically, we do not wish to deal with this complexity, as it would obscure our idea. Thus, we do \emph{not} adopt the universe technique.% % %paragraphName: our approach Instead, we follow a simpler and more limited approach. First, we give a formal (non-inductive) definition of the logical relation at every type constant. In \textsc{Agda}, the type constants are \texttt{\makebox[1.22ex][c]{\_{}}$ \rightarrow $\makebox[1.22ex][c]{\_{}}}, \texttt{\makebox[1.22ex][c]{$ \Pi $}}, \texttt{Set\makebox[0.61ex][l]{$ _{{0}} $}}, and the user-defined inductive data types, such as{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}}. Thus, to each such constant{~}$ \kappa $, we associate a relation, which we write{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \kappa $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. (Note that there are no spaces in this name{:} \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \kappa $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is just the name of a new constant. We are \emph{not} formally defining a function called{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}.) Thus, we define \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}, \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, and one constant per user-defined inductive data type, such as{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. Then, instead of giving a formal inductive definition of the logical relation at every type, we view the application of the logical relation to a type as an informal {``}macro-expansion{''} process. For instance, imagine we wish to compute the definition of the logical relation at type{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Bool}. We cannot write{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Bool\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, with spaces near the brackets, because we have not formally defined a function called{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. Instead, we manually distribute the semantic brackets over the arrows and write{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, without spaces near the brackets. Because we have formally defined the constants{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, and{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}, this is a valid \textsc{Agda} expression, whose meaning can be automatically computed by \textsc{Agda}.% % %paragraphName: ⟦Π⟧ The definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}} is just{~}\texttt{RelatedFunctions}\index{Code!\texttt{RelatedFunctions}}. The definition of{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} is a dependent version of{~}\texttt{RelatedFunctions}, where the relation that is required of the results is allowed to depend on the manner in which the arguments are related{:}% {\nopagebreak } % %code: % %comment: ⟦Π⟧ Aᵣ Bᵣ f₁ f₂ = ∀ {x₁ x₂} (xᵣ : Aᵣ x₁ x₂) % → Bᵣ xᵣ (f₁ x₁) (f₂ x₂) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⟦→⟧, ⟦∀⟧, and ⟦Set₀⟧ Following Bernardy et al.{~}\shortcite{bernardy-10}, the definition of the constant{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} is as follows{:}% {\nopagebreak } % %code: % %comment: ⟦Set₀⟧ : Set₀ → Set₀ → Set₁ %⟦Set₀⟧ A₁ A₂ = A₁ → A₂ → Set₀ % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{1}} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⟦Set₀⟧ and Reynolds The type{~}\texttt{A\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Set\makebox[0.61ex][l]{$ _{{0}} $}} is the type of all relations between the types{~}\texttt{A\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{A\makebox[0.61ex][l]{$ _{{2}} $}}. Although this definition may seem somewhat cryptic at first glance, it allows recovering Reynolds{'} definition of the logical relation at polymorphic types. In \textsc{Agda}, a polymorphic type is encoded as a dependent type of the form{~}\texttt{\makebox[1.22ex][l]{$ {(} $}A\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}$ \tau $}. By combining the above definitions of{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} and{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, one finds that the logical relation at such a polymorphic type involves a universal quantification over three things, namely two types{~}\texttt{A\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{A\makebox[0.61ex][l]{$ _{{2}} $}} and a relation{~}\texttt{A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} between these types. This is Reynolds{'} definition.% % %paragraphName: relations for data types We recall all of the above definitions in figure{~}\ref{rellogF}, and introduce some syntactic sugar. These definitions cover core type theory. Inductive data types are covered in a simple and systematic manner. The process is as follows{:} for each constructor{~}\texttt{$ \kappa $} of type{~}\texttt{$ \tau $}, declare a new constructor{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \kappa $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} whose type is \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \tau $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}$ \kappa $\makebox[1.22ex][c]{{~}}$ \kappa $}. Record types are treated in an analogous manner. As an illustration, the logical relations for the inductive data types that are used in this paper are given in figure{~}\ref{datarelF}.% % %paragraphName: ⟦_⟧ as a macro As announced earlier, we do not formally define a function{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. Instead, if{~}\texttt{$ \tau $} is a closed type, we view{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} as a {``}macro{''}, which can be manually expanded by replacing within{~}\texttt{$ \tau $} every constant{~}\texttt{$ \kappa $} with{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \kappa $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, every non-dependent arrow{~}\texttt{A\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B} with{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}B\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, every dependent arrow{~}\texttt{\makebox[1.22ex][l]{$ {(} $}x\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B} with{~}\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{{~}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\ensuremath{:}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}B\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, etc. By convention, we use the subscript{~}\texttt{r} in the expansion of dependent arrows. Here are a few examples of the manual expansion of the notation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}{:}% {\nopagebreak } % %code: % %comment: -- What we would like to write but cannot: %⟦ ℕ → ℕ → Bool ⟧ = %-- What we write instead: %⟦ℕ⟧ ⟦→⟧ ⟦ℕ⟧ ⟦→⟧ ⟦Bool⟧ = %-- What this means: %λ f₁ f₂ → % ∀ {x₁ x₂} (xᵣ : ⟦ℕ⟧ x₁ x₂) % {y₁ y₂} (yᵣ : ⟦ℕ⟧ y₁ y₂) % → ⟦Bool⟧ (f₁ x₁ y₁) (f₂ x₂ y₂) % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}What\mbox{\hspace{0.50em}}we\mbox{\hspace{0.50em}}would\mbox{\hspace{0.50em}}like\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}write\mbox{\hspace{0.50em}}but\mbox{\hspace{0.50em}}cannot{:}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}What\mbox{\hspace{0.50em}}we\mbox{\hspace{0.50em}}write\mbox{\hspace{0.50em}}instead{:}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}What\mbox{\hspace{0.50em}}this\mbox{\hspace{0.50em}}means{:}{\nopagebreak \newline% }\vphantom{$\{$}$ \lambda $\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][l]{\{{}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}y\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- The logical relation at a polymorphic type: %⟦ (A : Set₀) → A → A ⟧ = %⟦Π⟧ ⟦Set₀⟧ (λ Aᵣ → Aᵣ ⟦→⟧ Aᵣ) = %λ f₁ f₂ → % ∀ {A₁ A₂} (Aᵣ : A₁ → A₂ → Set₀) % {x₁ x₂} (xᵣ : Aᵣ x₁ x₂) % → Aᵣ (f₁ A₁ x₁) (f₂ A₂ x₂) % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}The\mbox{\hspace{0.50em}}logical\mbox{\hspace{0.50em}}relation\mbox{\hspace{0.50em}}at\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}polymorphic\mbox{\hspace{0.50em}}type{:}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}$ \lambda $\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- Using the notation instead of ⟦Π⟧: %⟦ (A : Set₀) → List A ⟧ = %⟨ Aᵣ ∶ ⟦Set₀⟧ ⟩⟦→⟧ ⟦List⟧ Aᵣ = %λ l₁ l₂ → % ∀ {A₁ A₂} (Aᵣ : A₁ → A₂ → Set₀) % → ⟦List⟧ Aᵣ (l₁ A₁) (l₂ A₂) % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}Using\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}notation\mbox{\hspace{0.50em}}instead\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{:}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}List\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}$ \lambda $\mbox{\hspace{0.50em}}l\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}l\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}List\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}l\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}l\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: figure \begin{figure*}[] \begin{flushleft} % %code: {\noindent}% %comment: ⟦Set₀⟧ : ∀ (A₁ A₂ : Set₀) → Set₁ %⟦Set₀⟧ A₁ A₂ = A₁ → A₂ → Set₀ % %⟦Set₁⟧ : ∀ (A₁ A₂ : Set₁) → Set₂ %⟦Set₁⟧ A₁ A₂ = A₁ → A₂ → Set₁ % %_⟦→⟧_ : ∀ {A₁ A₂ B₁ B₂} → ⟦Set₀⟧ A₁ A₂ → ⟦Set₀⟧ B₁ B₂ % → ⟦Set₀⟧ (A₁ → B₁) (A₂ → B₂) %Aᵣ ⟦→⟧ Bᵣ = λ f₁ f₂ → ∀ {x₁ x₂} → Aᵣ x₁ x₂ → Bᵣ (f₁ x₁) (f₂ x₂) % %infixr 0 _⟦→⟧_ % %⟦Π⟧ : ∀ {A₁ A₂} (Aᵣ : ⟦Set₀⟧ A₁ A₂) % {B₁ B₂} (Bᵣ : (Aᵣ ⟦→⟧ ⟦Set₀⟧) B₁ B₂) % → ((x : A₁) → B₁ x) → ((x : A₂) → B₂ x) → Set₁ %⟦Π⟧ Aᵣ Bᵣ = λ f₁ f₂ → ∀ {x₁ x₂} (xᵣ : Aᵣ x₁ x₂) → Bᵣ xᵣ (f₁ x₁) (f₂ x₂) % %syntax ⟦Π⟧ Aᵣ (λ xᵣ → f) = ⟨ xᵣ ∶ Aᵣ ⟩⟦→⟧ f % %⟦∀⟧ : ∀ {A₁ A₂} (Aᵣ : ⟦Set₀⟧ A₁ A₂) % {B₁ B₂} (Bᵣ : (⟦Set₀⟧ ⟦→⟧ ⟦Set₀⟧) B₁ B₂) % → ⟦Set₁⟧ ({x : A₁} → B₁ x) ({x : A₂} → B₂ x) %⟦∀⟧ Aᵣ Bᵣ = λ f₁ f₂ → ∀ {x₁ x₂} (xᵣ : Aᵣ x₁ x₂) → Bᵣ xᵣ (f₁ {x₁}) (f₂ {x₂}) % %syntax ⟦∀⟧ Aᵣ (λ xᵣ → f) = ∀⟨ xᵣ ∶ Aᵣ ⟩⟦→⟧ f % \vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{1}} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{1}} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{11.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}$ \lambda $\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}infixr\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}\makebox[1.22ex][l]{\{{}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{1}} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}$ \lambda $\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}syntax\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \Pi $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}f{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}\makebox[1.22ex][l]{\{{}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{\{{}}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{\{{}}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}$ \lambda $\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}syntax\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}f{\nopagebreak \newline% }\vphantom{$\{$}}% \end{flushleft} \caption{Logical relations for core type theory\label{rellogF}} \end{figure*}% % %paragraphName: figure \begin{figure}[] \begin{flushleft} % %code: {\noindent}% %comment: data ⟦⊥⟧ : ⟦Set₀⟧ ⊥ ⊥ where -- no constructors % %data ⟦Bool⟧ : ⟦Set₀⟧ Bool Bool where % ⟦true⟧ : ⟦Bool⟧ true true % ⟦false⟧ : ⟦Bool⟧ false false % %data ⟦ℕ⟧ : ⟦Set₀⟧ ℕ ℕ where % ⟦zero⟧ : ⟦ℕ⟧ zero zero % ⟦suc⟧ : (⟦ℕ⟧ ⟦→⟧ ⟦ℕ⟧) suc suc % %data _⟦⊎⟧_ {A₁ A₂ B₁ B₂} (Aᵣ : ⟦Set₀⟧ A₁ A₂) % (Bᵣ : ⟦Set₀⟧ B₁ B₂) : % A₁ ⊎ B₁ → A₂ ⊎ B₂ → Set₀ where % ⟦inj₁⟧ : (Aᵣ ⟦→⟧ Aᵣ ⟦⊎⟧ Bᵣ) inj₁ inj₁ % ⟦inj₂⟧ : (Bᵣ ⟦→⟧ Aᵣ ⟦⊎⟧ Bᵣ) inj₂ inj₂ % \vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \bot $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}\mbox{\hspace{0.50em}}where\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}no\mbox{\hspace{0.50em}}constructors{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}Bool\mbox{\hspace{0.50em}}Bool\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}true\mbox{\hspace{1.50em}}true{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}false\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}false\mbox{\hspace{1em}}false{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}zero\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{7em}}zero\mbox{\hspace{1em}}zero{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}suc\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}suc\mbox{\hspace{1.50em}}suc{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{:}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}A\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}inj\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}inj\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}B\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}}% \end{flushleft} \caption{Logical relations for inductive data types\label{datarelF}} \end{figure}% \paragraph{The parametricity hypothesis} % %paragraphName: intro As announced earlier, we assume that the \textsc{Agda} logical relation is universal. We can now state this assumption in a precise way{:}% \begin{quote} (Parametricity hypothesis for \textsc{Agda}) We assume that, for every well-typed term{~}\texttt{M} of closed type{~}\texttt{$ \tau $}, the theorem{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}M\makebox[1.22ex][c]{{~}}M} is provable. \end{quote} \paragraph{} % %paragraphName: price Because{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is an informal notation, as opposed to an \textsc{Agda} function, the above hypothesis must be stated in an informal manner. Nevertheless, for a specific type{~}\texttt{$ \tau $}, it is possible to give a formal statement of this hypothesis. For instance, in section{~}\ref{usingParam}, where we prove that {``}world-polymorphic functions commute with renamings{''}, we explicitly and formally use a hypothesis of the form{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}f\makebox[1.22ex][c]{{~}}f}, for a specific type{~}\texttt{$ \tau $} and for a specific term{~}\texttt{f}.% % %paragraphName: abstraction theorem in Agda We warmly encourage the reader to study Bernardy et al.{~}\shortcite{bernardy-10} in order to understand the subject in greater depth.% % %paragraphName: free-theorem The theorems obtained by instantiating the parametricity hypothesis with a specific type{~}\texttt{$ \tau $} are known as {``}free theorems{''} \cite{wadler-free-89} because they allows us to establish a property of a term{~}\texttt{M} of type{~}\texttt{$ \tau $} without requiring us to reason about the definition of{~}\texttt{M}. Usually, this property is non-trivial only if the type{~}\texttt{$ \tau $} involves polymorphism. Indeed, in this case, the statement of the {``}free theorem{''} begins with universal quantifiers that can be instantiated in useful ways. In our setting, polymorphism arises out of two distinct sources. First, because the types defined by our library are abstract, the client must be polymorphic with respect to these types. Hence, the free theorem about the client begins with a series of universal quantifiers which we can instantiate in a suitable manner. Second, when the client defines a world-polymorphic function, this particular function comes with a powerful {``}free theorem{''}. Later on (section{~}\ref{strengthThm}), we give a more detailed account to various function types and the strength of their associated {``}free theorems{''}.% \subsection{An example{:} Boolean values represented by numbers\label{boolRelS}} % %paragraphName: describe our bool as ℕ example Logical relations help understand in what sense the interface offered by an abstract type is safe, or in other words, in what sense the abstraction offered by the interface is independent of the underlying representation \cite{reynolds-83,mitchell-86}. In order to explain this, we introduce a tiny example, where Boolean values are represented using natural numbers. We want{~}0 to represent{~}\texttt{false} and any other number to represent{~}\texttt{true}. Therefore, Boolean disjunction can be implemented using addition. We show that logical relations help build a {``}model{''} and ensure that an implementation respects this model. Then, parametricity can be used to show that a client that uses only the interface must also respect the model.% % %paragraphName: description of B implem Our tiny implementation of Booleans using natural numbers is given below. It contains a type{~}\texttt{B}\index{Code!\texttt{B}} that we want to keep abstract. It contains obvious definitions for{~}\texttt{true}\index{Code!\texttt{true}}, \texttt{false}\index{Code!\texttt{false}}, and disjunction{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}}}. Furthermore, it intentionally offers a dubious operation,{~}\texttt{is42?}\index{Code!\texttt{is42?}}.% {\nopagebreak } % %code: % %comment: B : Set %B = ℕ % ~\\~\vphantom{$\{$}\texttt{B\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}B\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: false : B %false = 0 % \vphantom{$\{$}\texttt{false\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}B{\nopagebreak \newline% }\vphantom{$\{$}false\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}0{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: true : B %true = 1 % \vphantom{$\{$}\texttt{true\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}B{\nopagebreak \newline% }\vphantom{$\{$}true\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}1{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: _∨_ : B → B → B %m ∨ n = m + n % \vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B{\nopagebreak \newline% }\vphantom{$\{$}m\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\vee}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}m\mbox{\hspace{0.50em}}+\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: is42? : B → B %is42? 42 = true %is42? _ = false % \vphantom{$\{$}\texttt{is42?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B{\nopagebreak \newline% }\vphantom{$\{$}is42?\mbox{\hspace{0.50em}}42\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}true{\nopagebreak \newline% }\vphantom{$\{$}is42?\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: introduce ⟦B⟧ The function{~}\texttt{is42?}\index{Code!\texttt{is42?}} is intuitively not {``}well-behaved{''} because, even though the natural numbers{~}41 and{~}42 both encode the Boolean value{~}\texttt{true}, this function maps them to distinct results. Thus, we wish to define a criterion that allows us to easily and formally tell which operations are safe and which are not. To begin, we define a binary relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} over the type{~}\texttt{B}. The idea is, two natural numbers are related if and only if they have the same meaning, that is, if and only if they encode the same truth value. This relation is an {``}invariant{''} which every operation must preserve. Technically, we define{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} as an inductive data type. Its definition states that{~}0 is related with itself and that any two non-zero numbers are related.% {\nopagebreak } % %code: % %comment: data ⟦B⟧ : B → B → Set where % ⟦false⟧ : ⟦B⟧ 0 0 % ⟦true⟧ : ∀ {m n} → ⟦B⟧ (suc m) (suc n) % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}false\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}0{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}m\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}m\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: unary versus binary In this approach, one explicitly defines when two values mean {``}the same thing{''}, but one does not explicitly define what that {``}thing{''} is. In this toy example, one could easily adopt a different (and simpler) approach, where one explicitly defines that{~}0 represents{~}\texttt{false} and that any other number represents{~}\texttt{true}. There would naturally follow that two numbers are equivalent if and only if they represent the same truth value. This works well because the inhabitants of our intended model, namely the Boolean values, have a canonical representation. In our real-world application, where the problem is to define $ \alpha $-equivalence at every type, it is easier to define when two terms are {``}equivalent{''} than it is to map every term to a canonical representative. This is why logical relations seem particularly natural and useful in our setting.% % %paragraphName: plugging ⟦B⟧ Defining{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} suffices to define the logical relation at every type. This defines what we view as {``}good behavior{''}. If a piece of client code has type{~}\texttt{$ \tau $}, we expect it to satisfy the free theorem \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. The reader might wonder, however, why we are allowed to choose the definition of{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. After all, since{~}\texttt{B} is internally defined as{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}}, mustn{'}t we define{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} as{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}? If we define{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} in some other way, how do we know that the logical relation is still universal? To see why this makes sense, consider a client of the library. This client can be thought of as a function that expects an implementation of the library as an argument. Thus, this function is parameterized over the type{~}\texttt{B} and over the operations{~}\texttt{true}, \texttt{false}, \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}}, and{~}\texttt{is42?}. In other words, this function is polymorphic in{~}\texttt{B}. Thus, the {``}theorem for free{''} that comes with this function is universally quantified with respect to{~}\texttt{B} \emph{and with respect to a relation}{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. This explains why we may define the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} however we please.% % %paragraphName: proof obligations when plugging ⟦B⟧ Naturally, we must still satisfy a few proof obligations. The {``}theorem for free{''} that comes with the client is further parameterized with the operations \texttt{true}, \texttt{false}, \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}}, \texttt{is42?} \emph{and with proofs}{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}false\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}, \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}is42?\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} \emph{that each of these operations is well-behaved}. That is, we must prove that each of the operations offered by the library is related to itself.% % %paragraphName: meeting the proof obligations when plugging ⟦B⟧ The data constructors{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} and{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}false\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}false\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} are obvious witnesses to the fact that the operations{~}\texttt{true} and{~}\texttt{false} are well-behaved. The remains to check whether{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}} and{~}\texttt{is42?} are well-behaved. Every time, the statement that must be proved is constructed in a systematic manner{:} if an operation has type{~}\texttt{$ \tau $}, then one must check that its implementation is related to itself by the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. For instance, here is the statement that must be proven about{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}}}{~}{:}% {\nopagebreak } % %code: % %comment: _⟦∨⟧_ : (⟦B⟧ ⟦→⟧ ⟦B⟧ ⟦→⟧ ⟦B⟧) _∨_ _∨_ % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _⟦∨⟧_'s type, description Once unfolded, this statement looks like this{:}% {\nopagebreak } % %code: % %comment: _⟦∨⟧_ : ∀ {x₁ x₂} (xᵣ : ⟦B⟧ x₁ x₂) % {y₁ y₂} (yᵣ : ⟦B⟧ y₁ y₂) % → ⟦B⟧ (x₁ ∨ y₁) (x₂ ∨ y₂) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}\makebox[1.22ex][l]{\{{}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}y\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\vee}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\vee}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _⟦∨⟧_ description This proposition states that the disjunction operation maps related arguments to related results. Now, thanks to the inductive definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}+\makebox[1.22ex][c]{\_{}}}, pattern-matching on the first relation argument suffices to cause the goal to reduce. Thus, we are able to offer the following nice-looking definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}, which one can recognize as the usual lazy definition of left-biased disjunction{:}% {\nopagebreak } % %code: % %comment: ⟦false⟧ ⟦∨⟧ x = x %⟦true⟧ ⟦∨⟧ _ = ⟦true⟧ % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}false\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}x\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{1em}}x{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{\ensuremath{\vee}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ¬⟦is42?⟧ description Let us now consider the question of the well-behavedness of the function{~}\texttt{is42?}. Of course, there is no proof that this function is well-behaved. In fact, it is easy to prove that it is ill-behaved. It suffices to exhibit two related inputs, say{~}42 and{~}27, that are mapped to non-related outputs (we have \texttt{is42?\makebox[1.22ex][c]{{~}}42\makebox[1.22ex][c]{{~}}{\char `\=}\makebox[1.22ex][c]{{~}}1} and{~}\texttt{is42?\makebox[1.22ex][c]{{~}}27\makebox[1.22ex][c]{{~}}{\char `\=}\makebox[1.22ex][c]{{~}}0}).% {\nopagebreak } % %code: % %comment: ¬⟦is42?⟧ : ¬((⟦B⟧ ⟦→⟧ ⟦B⟧) is42? is42?) %¬⟦is42?⟧ ⟦is42?⟧ with ⟦is42?⟧ {42} {27} ⟦true⟧ %... | () -- absurd % ~\\~\vphantom{$\{$}\texttt{\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}is42?\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}is42?\mbox{\hspace{0.50em}}is42?\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}is42?\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}is42?\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}with\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}is42?\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}42\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}27\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{9em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}absurd{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: model vs interface only Note that{~}\texttt{is42?} is rejected by our model with no consideration of which other operations are exported. Once the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}B\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is defined, it suffices to {``}turn the crank{''} to find out that{~}\texttt{is42?} is ill-behaved. This modularity is precious and has helped us easily determine which operations could or could not be offered as part of the \textsc{NomPa} library.% \subsection{Relations for \textsc{NomPa}\label{nompaRel}} % %paragraphName: same process as for B For \textsc{NomPa}, we apply the same process as in the toy example. We define our expectations by defining a relation for each of the abstract types that the library advertises. Then, we prove that each operation offered by the library is well-behaved with respect to the logical relation that arises out of these definitions.% \subsubsection{Relations for \textsc{NomPa} types} % %paragraphName: ⟦NomPaTypes⟧ fig For reference, the definitions are given in figure{~}\ref{nompaRelTypesF}. We now describe them in turn.% % %paragraphName: ⟦World⟧ are relations The first thing to do is to define the constant{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. What does it mean for two worlds to be related? It is useful to think of the manner in which{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is defined. Recall that it is defined by the equation \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}A\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}{\char `\=}}{ }\texttt{A\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}A\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Set\makebox[0.61ex][l]{$ _{{0}} $}}. This means that the {``}theorem for free{''} that describes a polymorphic object is universally quantified over two types{~}\texttt{A\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{A\makebox[0.61ex][l]{$ _{{2}} $}} and over a relation{~}\texttt{A\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} between these types. Now, we would like to define{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} in such a way that, similarly, the {``}theorem for free{''} that describes a world-polymorphic object is universally quantified over two worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}} and over a relation between these worlds.% % %paragraphName: functional and injective Thus, it seems that we could perhaps let{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}} be \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Set\makebox[0.61ex][l]{$ _{{0}} $}}, that is, the set of all relations between (the sets of names denoted by){~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}}. However, if we adopted such a definition, we would later be unable to prove that the name comparison operation{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}} is well-behaved. Because this operation is world-polymorphic, we will have to prove that, for all worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}} and \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}} and for every relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} of type \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}}, this operation maps \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}-related arguments to \emph{equal} results. (Indeed, the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is just equality.) If{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} was allowed to range over arbitrary relations, it would follow that{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}} must be a constant function. Thus, we must restrict the set of allowable relations. It is clear that the equality test{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}} is well-behaved if and only if every relation in \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}} preserves equality in both directions, i.e., is functional and injective{:}\index{Code!\texttt{Preserve-$ \equiv $}}% {\nopagebreak } % %code: % %comment: Preserve-≡ ℛ = % ∀ x₁ y₁ x₂ y₂ → ℛ x₁ x₂ → ℛ y₁ y₂ % → x₁ ≡ y₁ ↔ x₂ ≡ y₂ % ~\\~\vphantom{$\{$}\texttt{Preserve-$ \equiv $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{7.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \leftrightarrow $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: functional and injective: all of them We allow{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}} to contain all such relations. Thus, the {``}theorem for free{''} that describes a world-polymorphic object will be universally quantified over two worlds and over a functional and injective relation between them. In other words, we choose the definition of{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} that leads to the strongest possible {``}free theorems{''}, under the requirement that{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}} be well-behaved. It turns out that, with this definition, we will be able to prove that every other operation is well-behaved too.% % %paragraphName: ⟦Name⟧ Because the type \texttt{Name} is parameterized with a world, the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} is parameterized with a relation between worlds. It is defined as \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} the identity{:} two names are related by{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} if and only if they are related by{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}.% % %paragraphName: ⟦Binder⟧ The definition of the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} is surprisingly simple{:} it is the full relation. Thus, every two binders are related by{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}. Thus, a function that allows distinguishing between two binders is considered ill-behaved. This is consistent with our goal of disallowing functions that distinguish between two $ \alpha $-equivalent representations of a $ \lambda $-term.% % %paragraphName: Binder→Binder→Bool are constant functions A consequence of this definition is that the library cannot provide an equality test over binders. Indeed, as demonstrated by the following theorem, if{~}\texttt{f} is a function of type{~}\texttt{Binder}{ }\texttt{$ \rightarrow $\makebox[1.22ex][c]{{~}}Binder\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Bool}, then it must be a constant function.% {\nopagebreak } % %code: % %comment: -- ⟦f⟧ is the parametricity theorem for f %⟦f⟧ : (⟦Binder⟧ ⟦→⟧ ⟦Binder⟧ ⟦→⟧ ⟦Bool⟧) f f % %-- f-const is a corollary of ⟦f⟧. %-- f-const shows that f is a constant function. %f-const : ∀ x₁ x₂ y₁ y₂ → f x₁ y₁ ≡ f x₂ y₂ %f-const x₁ x₂ y₁ y₂ with ⟦f⟧ {x₁} {x₂} _ {y₁} {y₂} _ %... | ⟦true⟧ = refl %... | ⟦false⟧ = refl % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}f\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}parametricity\mbox{\hspace{0.50em}}theorem\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}f{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}f\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}f{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}f-const\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}corollary\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}f\makebox[1.22ex][c]{\ensuremath{\rrbracket}}.{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}f-const\mbox{\hspace{0.50em}}shows\mbox{\hspace{0.50em}}that\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}constant\mbox{\hspace{0.50em}}function.{\nopagebreak \newline% }\vphantom{$\{$}f-const\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}f-const\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}with\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}f\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}y\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}true\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}refl{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}false\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}refl{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _⟦⊆⟧_ Next, we define the relation{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}}. Again, we wish to adopt the most liberal definition with respect to which we can prove that the operations offered by the library are well-behaved. For this purpose, we exploit the fact there is ultimately only one way to use an inclusion witness, which is to pass it as an argument to the operation{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}}. Thus, we posit that two world inclusion witnesses{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}} are related if and only if{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}} are related (see figure{~}\ref{nompaRelTypesF}). Although this definition is arguably quite elegant, it may seem somewhat {``}magic{''} and opaque. Fortunately, one can formulate an equivalent definition in terms of inclusion of relations. Let us say that a relation{~}\texttt{\makebox[1.83ex][c]{$ \mathcal{{R}} $}\makebox[0.61ex][l]{$ _{{1}} $}} is a subset of a relation{~}\texttt{\makebox[1.83ex][c]{$ \mathcal{{R}} $}\makebox[0.61ex][l]{$ _{{2}} $}} if and only if every pair that is related by{~}\texttt{\makebox[1.83ex][c]{$ \mathcal{{R}} $}\makebox[0.61ex][l]{$ _{{1}} $}} is related by{~}\texttt{\makebox[1.83ex][c]{$ \mathcal{{R}} $}\makebox[0.61ex][l]{$ _{{2}} $}} as well. Then, two relations{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} and{~}\texttt{\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} are related by{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}} if and only if{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is a subset of{~}\texttt{\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}. Indeed, if one considers the definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}} in figure{~}\ref{nompaRelTypesF} and expands the definitions of{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} and{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}, one finds{:}% {\nopagebreak } % %code: % %comment: _⟦⊆⟧_ αᵣ βᵣ α₁⊆β₁ α₂⊆β₂ % = ∀ {x₁ x₂} → (x₁ , x₂) ∈ αᵣ % → (coerceᴺ α₁⊆β₁ x₁ , coerceᴺ α₂⊆β₂ x₂) ∈ βᵣ % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _⟦⊆⟧_ suite Because the function{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}} behaves (after erasure) as the identity function, the right-hand side of the above equation informally means that the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is a subset of the relation{~}\texttt{\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}.% % %paragraphName: figure \begin{figure}[] \begin{flushleft} % %code: {\noindent}% %comment: Preserve-≡ : {A B : Set₀} (ℛ : A → B → Set₀) → Set₀ %Preserve-≡ ℛ = % ∀ x₁ y₁ x₂ y₂ → ℛ x₁ x₂ → ℛ y₁ y₂ % → x₁ ≡ y₁ ↔ x₂ ≡ y₂ % %-- ⟦World⟧ : ⟦Set₁⟧ World World %record ⟦World⟧ (α₁ α₂ : World) : Set₁ where % constructor _,_ % field % ℛ : Name α₁ → Name α₂ → Set % ℛ-pres-≡ : Preserve-≡ ℛ % %⟦Name⟧ : (⟦World⟧ ⟦→⟧ ⟦Set₀⟧) Name Name % -- : ∀ {α₁ α₂} → ⟦World⟧ α₁ α₂ → Name α₁ → Name α₂ → Set %⟦Name⟧ (ℛ , _) x₁ x₂ = ℛ x₁ x₂ % %⟦Binder⟧ : ⟦Set₀⟧ Binder Binder % -- : Binder → Binder → Set %⟦Binder⟧ _ _ = ⊤ % %⟦ø⟧ : ⟦World⟧ ø ø %⟦ø⟧ = (λ _ _ → ⊥) , (λ()) % %_⟦◅⟧_ : (⟦Binder⟧ ⟦→⟧ ⟦World⟧ ⟦→⟧ ⟦World⟧) _◅_ _◅_ % -- not proper Agda %bᵣ ⟦◅⟧ αᵣ ≝ { (b₁, b₂) } ∪ { (x, y) | (x, y) ∈ αᵣ ∧ x ≢ b₁ ∧ y ≢ b₂ } % %_⟦#⟧_ : (⟦Binder⟧ ⟦→⟧ ⟦World⟧ ⟦→⟧ ⟦Set₀⟧) _#_ _#_ % -- : ∀ {b₁ b₂} → ⟦Binder⟧ b₁ b₂ → ∀ {α₁ α₂} → ⟦World⟧ α₁ α₂ % -- → b₁ # α₁ → b₂ # α₂ → Set %_⟦#⟧_ _ _ _ _ = ⊤ % %_⟦⊆⟧_ : (⟦World⟧ ⟦→⟧ ⟦World⟧ ⟦→⟧ ⟦Set₀⟧) % _⊆_ _⊆_ % -- : ∀ {α₁ α₂} → ⟦World⟧ α₁ α₂ → % -- ∀ {β₁ β₂} → ⟦World⟧ β₁ β₂ → % -- α₁ ⊆ β₁ → α₂ ⊆ β₂ → Set %_⟦⊆⟧_ αᵣ βᵣ α₁⊆β₁ α₂⊆β₂ % = (⟦Name⟧ αᵣ ⟦→⟧ ⟦Name⟧ βᵣ) (coerceᴺ α₁⊆β₁) (coerceᴺ α₂⊆β₂) % \vphantom{$\{$}\texttt{Preserve-$ \equiv $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}A\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}B\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{0}} $}{\nopagebreak \newline% }\vphantom{$\{$}Preserve-$ \equiv $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}{\char `\=}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{7.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \leftrightarrow $\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{2.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}record\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}constructor\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}},\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}field{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{4em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}-pres-$ \equiv $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Preserve-$ \equiv $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}Name{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}--\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}Binder{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}--\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Binder\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \top $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4.50em}}--\mbox{\hspace{0.50em}}not\mbox{\hspace{0.50em}}proper\mbox{\hspace{0.50em}}Agda{\nopagebreak \newline% }\vphantom{$\{$}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{\stackrel{\mathtt{{\scriptscriptstyle def}}}{=}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{$ _{{1}} $},\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \cup $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x,\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x,\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\#{}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\#{}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}--\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}--\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\#{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\#{}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \top $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Set\makebox[0.61ex][l]{$ _{{0}} $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}--\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}--\mbox{\hspace{1.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}--\mbox{\hspace{2.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \beta $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% \end{flushleft} \caption{Relations for \textsc{NomPa} types\label{nompaRelTypesF}} \end{figure}% % %paragraphName: ⟦ø⟧ We now define{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} and{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}}. Whereas{~}\texttt{\makebox[1.22ex][c]{$ \emptyset $}} is a world, \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is a relation between the empty world and itself. We have no choice{:} there is only one such relation, namely the empty relation. We show its type and omit its definition{:}% {\nopagebreak } % %code: % %comment: ⟦ø⟧ : ⟦World⟧ ø ø % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⟦◅⟧ Whereas{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}} maps a binder and a world to a new world, \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}} maps a pair of binders and a relation between worlds to a new relation between worlds. In other words, it extends an existing relation between worlds, say{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, with a new pair of binders, say{~}\texttt{b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}. How should we define{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}? An idea that naturally comes to mind is to construct the set-theoretic union of the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} and of the singleton set{~}\{{}b\ensuremath{_{{r}}}\}{}. However, this would not make sense{:} we must be careful to ensure that the resulting relation is functional and injective. If the first component of the pair{~}\texttt{b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is already a member of the domain of the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, or (symmetrically) if the second component of{~}\texttt{b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is already a member of the codomain of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, then the set-theoretic union of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} and{~}\{{}b\ensuremath{_{{r}}}\}{} might not be functional and injective. This corresponds to a situation where a new binder {``}shadows{''} a previous one. In that case, we would like the new pair{~}\texttt{b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} to take precedence over any earlier bindings. Thus, the definition that we ultimately adopt can be described as the set-theoretic union of the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, \emph{deprived of any bindings that conflict with{~}\texttt{b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}}, and of the singleton set{~}\{{}b\ensuremath{_{{r}}}\}{}. It can be informally defined as follows{:}% {\nopagebreak } % %code: % %comment: _⟦◅⟧_ : (⟦Binder⟧ ⟦→⟧ ⟦World⟧ ⟦→⟧ ⟦World⟧) _◅_ _◅_ % -- not proper Agda %bᵣ ⟦◅⟧ αᵣ ≝ { (b₁, b₂) } ∪ { (x, y) | (x, y) ∈ αᵣ ∧ x ≢ b₁ ∧ y ≢ b₂ } % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4.50em}}--\mbox{\hspace{0.50em}}not\mbox{\hspace{0.50em}}proper\mbox{\hspace{0.50em}}Agda{\nopagebreak \newline% }\vphantom{$\{$}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{\stackrel{\mathtt{{\scriptscriptstyle def}}}{=}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{$ _{{1}} $},\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \cup $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x,\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x,\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \in $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: drawing The effect of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}} is illustrated in figure{~}\ref{consingF}.% % %paragraphName: figure \begin{figure}[] \begin{flushleft} \begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path[-] (0L) edge node [above]{}(3R); \path[-] (3L) edge node [above]{}(0R); \path[-] (2L) edge node [above]{}(2R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path node (4L)[above of=3L]{$ \bullet $}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{4}; \path node (4R)[right of=4L,right=1cm of 4L]{$ \bullet $}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{4}; \path[-] (4L) edge node [above]{}(2R); \path[-] (0L) edge node [above]{}(3R); \path[-] (3L) edge node [above]{}(0R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}4,2\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path node (4L)[above of=3L]{$ \bullet $}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{4}; \path node (4R)[right of=4L,right=1cm of 4L]{$ \bullet $}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{4}; \path[-] (4L) edge node [above]{}(4R); \path[-] (0L) edge node [above]{}(3R); \path[-] (3L) edge node [above]{}(0R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}4,4\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\langle}}4,2\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} \end{center} \end{minipage} \end{flushleft} \caption{The effect of \texttt{\_{}\ensuremath{\llbracket}\ensuremath{\triangleleft}\ensuremath{\rrbracket}\_{}} on relations\label{consingF}} \end{figure}% \subsubsection{\textsc{NomPa} values fit the relation} % %paragraphName: zeroᴮ, sucᴮ, _#ø, suc#, nameᴮ, and ¬Nameø We now give a short overview of the proofs needed to show that the operations offered by the library fit the relation. Formally, for each operation{~}\texttt{p} of type{~}\texttt{$ \tau $} that appears in the interface of the library, we have to exhibit a proof{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}p\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} of the statement{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{~}}$ \tau $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}p\makebox[1.22ex][c]{{~}}p}. All proofs can be found online{~}% %comment: Code Reference: NomPa.Implem.LogicalRelation.Internals % \cite{nompa-pouillard-11}.% % %paragraphName: many are immediate Many of these proofs are immediate. For instance, because the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is the full relation, any operation whose return type is{~}\texttt{Binder} is well-behaved. For some operations, the proof is just a matter of expanding the definitions. For instance, in the case of the operation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}name\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, which converts a binder to a name, the statement that must be proved is the following{:}% {\nopagebreak } % %code: % %comment: ⟦nameᴮ⟧ : (∀⟨ αᵣ ∶ ⟦World⟧ ⟩⟦→⟧ % ⟨ bᵣ ∶ ⟦Binder⟧ ⟩⟦→⟧ % ⟦Name⟧ (bᵣ ⟦◅⟧ αᵣ) % ) nameᴮ nameᴮ %-- : ∀ {α₁ α₂} (αᵣ : ⟦World⟧ α₁ α₂) %-- {b₁ b₂} (bᵣ : ⟦Binder⟧ b₁ b₂) %-- → ⟦Name⟧ (bᵣ ⟦◅⟧ αᵣ) (nameᴮ {α₁} b₁) (nameᴮ {α₂} b₂) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}name\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \forall $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5em}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}name\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{3em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{5em}}\makebox[1.22ex][l]{\{{}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Binder\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{4em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: many are immediate (continued) That is, roughly speaking, we must prove that the names{~}\texttt{b\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{b\makebox[0.61ex][l]{$ _{{2}} $}} are related by the relation{~}\texttt{b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}. This follows immediately from the definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}, since the effect of this operation is precisely to extend the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} with the pair{~}\texttt{\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}},\makebox[1.22ex][c]{{~}}b\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}}.% % %paragraphName: ==ᴺ In the case of the equality test{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}}, once unfolded, the statement requires that the equality test commute with a renaming. In other words, the outcome of an equality test must not change when its inputs are consistently renamed.% {\nopagebreak } % %code: % %comment: _⟦==ᴺ⟧_ : (∀⟨ αᵣ ∶ ⟦World⟧ ⟩⟦→⟧ % ⟦Name⟧ αᵣ ⟦→⟧ % ⟦Name⟧ αᵣ ⟦→⟧ % ⟦Bool⟧ % ) _==ᴺ_ _==ᴺ_ %-- : ∀ {α₁ α₂} (αᵣ : ⟦World⟧ α₁ α₂) %-- {x₁ x₂} (xᵣ : ⟦Name⟧ αᵣ x₁ x₂) %-- {y₁ y₂} (yᵣ : ⟦Name⟧ αᵣ y₁ y₂) %-- → ⟦Bool⟧ (x₁ ==ᴺ y₁) (x₂ ==ᴺ y₂) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \forall $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5em}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{3em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{5em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{5em}}\makebox[1.22ex][l]{\{{}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}y\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{4em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ==ᴺ (continued) The proof is in two parts. First, we prove that the Boolean-valued function{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}} decides propositional equality on names. Second, we exploit the fact that the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} preserves equality, that is,{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is functional and injective.% % %paragraphName: exportᴺ? The proof that{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?} is in the relation relies on two points. First, the success of{~}\texttt{\makebox[1.22ex][l]{$ {(} $}export\makebox[0.61ex][l]{\textsuperscript{N}}?\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}b\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}x\makebox[1.22ex][r]{$ {)} $}} (that is, whether it returns{~}\texttt{just} or{~}\texttt{nothing}) depends only on the equality between{~}\texttt{\makebox[1.22ex][l]{$ {(} $}name\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][c]{{~}}b\makebox[1.22ex][r]{$ {)} $}} and{~}\texttt{x}. Second, every pair in the relation{~}\texttt{\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}} is either in the relation{~}\texttt{\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}} or in the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}. This follows from our definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}.% % %paragraphName: coerceᴺ and ⊆ rules Thanks to the definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}}}, the proof that{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}} is well-behaved is immediate. There remains to show that each of the world inclusion rules (figure{~}\ref{nompaIfaceF}) is well-behaved. This can be done informally by a simple inspection of these rules, while keeping in mind that a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} must now interpreted as a relation between worlds and world inclusion{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{\_{}}} must now be interpreted as inclusion of relations. In the last rule, \texttt{\makebox[1.83ex][c]{$ \subseteq $}-\#{}}, we can now see why the freshness hypothesis \texttt{b\makebox[1.22ex][c]{{~}}\#{}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} is required. Indeed, the goal is to prove that the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is a subset of the relation{~}\texttt{\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}}. In the absence of any hypothesis about{~}\texttt{b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, this is false, because the operation{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}} can deprives{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} of certain pairs if there is shadowing. In the presence of the above freshness hypothesis, we can further assume that{~}\texttt{b\makebox[0.61ex][l]{$ _{{1}} $}} is not in the domain of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} and that{~}\texttt{b\makebox[0.61ex][l]{$ _{{2}} $}} is not in the codomain of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}. In this case, \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is indeed a subset of{~}\texttt{\makebox[1.22ex][l]{$ {(} $}b\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}}.% \subsubsection{An example of an ill-behaved operation} % %paragraphName: _<=ᴺ_ Consider the following function, which exposes a total ordering on names{:}% {\nopagebreak } % %code: % %comment: _<=ᴺ_ : ∀ {α} → Name α → Name α → Bool %(m , _) <=ᴺ (n , _) = ℕ._<=_ m n % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Bool{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][l]{$ {(} $}m\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}n\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}.\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}m\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _<=ᴺ_ broken This operation is well-typed. Yet, it is ill-behaved, because its outcome \emph{can} change when its inputs are consistently renamed.% {\nopagebreak } % %code: % %comment: ¬⟦<=ᴺ⟧ : ¬((∀⟨ αᵣ ∶ ⟦World⟧ ⟩⟦→⟧ % ⟦Name⟧ αᵣ ⟦→⟧ % ⟦Name⟧ αᵣ ⟦→⟧ ⟦Bool⟧) _<=ᴺ_ _<=ᴺ_) %-- : ¬(∀ {α₁ α₂} (αᵣ : ⟦World⟧ α₁ α₂) %-- {x₁ x₂} (xᵣ : ⟦Name⟧ αᵣ x₁ x₂) %-- {y₁ y₂} (yᵣ : ⟦Name⟧ αᵣ y₁ y₂) %-- → ⟦Bool⟧ (x₁ <=ᴺ y₁) (x₂ <=ᴺ y₂)) %¬⟦<=ᴺ⟧ ⟦<=⟧ = ¬⟦Bool⟧-true-false (⟦<=⟧ ? {0 , _} {1 , _} ? % {1 , _} {0 , _} ?) % -- parts (`?') of the proof are omitted for conciseness % ~\\~\vphantom{$\{$}\texttt{\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \forall $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{2.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{2.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{2.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2.50em}}\makebox[1.22ex][l]{\{{}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}y\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{2.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}y\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \neg $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}-true-false\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\textless{}}{\char `\=}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}?\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}0\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}1\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}?{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}\makebox[1.83ex][l]{ }\mbox{\hspace{14em}}\makebox[1.22ex][l]{\{{}}1\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}0\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}?\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}--\mbox{\hspace{0.50em}}parts\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}{`}?{'}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}proof\mbox{\hspace{0.50em}}are\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}for\mbox{\hspace{0.50em}}conciseness{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: pointer This explains why, even though this operation would be pragmatically useful in certain circumstances (see section \ref{workingWithEnvS}), it cannot be made part of the library.% \subsection{What does this mean?\label{tmAlphaEquivS}} % %paragraphName: everything is proved We have formally proved that every operation offered by the library is well-behaved with respect to the logical relation{~}\cite{nompa-pouillard-11}. By combining this fact with the parametricity hypothesis for \textsc{Agda}, there follows that every well-typed client of our library is also well-behaved with respect to our logical relation.% % %paragraphName: impact What is the impact of the result? In order to find out, one must examine the theorem that comes {``}for free{''} \cite{wadler-free-89} with clients of various type.% % %paragraphName: impact 1 Consider, for instance, a client of type{~}\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Bool}, that is, a function{~}\texttt{f} that maps a closed $ \lambda $-term to a Boolean result. The {``}free theorem{''} guarantees that this function maps \texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}}-related terms to \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}-related results. In the first conference paper{~}\cite{pouillard-pottier-10}, we informally prove that the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} coincides with our intuitive notion of $ \alpha $-equivalence of $ \lambda $-terms. (We do not produce a machine-checked version of this proof, although it would admittedly be desirable to do so.) Furthermore, the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Bool\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is equality. Thus, the {``}free theorem{''} guarantees that the function{~}\texttt{f} maps two $ \alpha $-equivalent terms to the same result. In short, a well-typed client cannot distinguish two $ \alpha $-equivalent (closed) terms.% % %paragraphName: impact 2 There are other types that come with interesting {``}free theorems{''}. For instance, consider a world-polymorphic and homogeneous term transformer, that is, a client function{~}\texttt{f} of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. The {``}free theorem{''} associated with this type guarantees that, for every relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, this function maps \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}-related arguments to \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}-related results. Furthermore, one can prove that two terms are related by{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} if and only if their free names are related by{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} and these terms are otherwise $ \alpha $-equivalent. Thus, we find that{~}\texttt{f} must commute with an arbitrary renaming of the free names. In other words, \texttt{f} is equivariant{~}\cite{pitts-06}.% % %paragraphName: impact 3 We do not formally prove the above claims. After we extend the library with support for de Bruijn indices, we come back to this issue and formally prove (with respect to a de Bruijn representation of terms) that world-polymorphic homogeneous term transformers commute with renamings (section \ref{usingParam}).% \section{Introduction to de Bruijn indices\label{deBruijnS}} % %paragraphName: we focus on nameless So far, we have focused on the representation of object-level terms in nominal style, and we have presented only a fragment of the library, which is sufficient to support this style. This way, we hope to avoid some of the confusion that could have resulted if we had decided to deal at once with multiple representation styles. We now focus on the representation of syntax with names and binders via de Bruijn indices{~}\cite{de-bruijn-72}. This representation is sometimes referred to as {``}nameless{''} because binders disappear completely, while names are no longer represented by atoms but by their {``}distance{''} to the point where they were bound. However, in spite of the important differences that exist between the nominal representation and de Bruijn{'}s representation, the two representations ultimately also exhibit several common points. For instance, in both representations, names are just natural numbers. Also, in both settings, we wish to exclude certain ill-behaved pieces of code. In the de Bruijn setting, for instance, we would like to reject a piece of code where the programmer omits to {``}shift{''} a de Bruijn index. Quite surprisingly perhaps, it turns out that, in order to support de Bruijn indices, we do not need to throw away any of the infrastructure that we have constructed up to this point. All we need to do is \emph{extend} the library{'}s interface, implementation, and soundness proof with a small number of new types and operations.% % %paragraphName: plan In the remainder of this section, we informally introduce de Bruijn indices and go through several variations on {``}well-typed de Bruijn indices{''} that exist in the literature. In the sections that follow, we extend the library{'}s interface and implementation (section{~}\ref{napaS}). We explain how to use the library so as to define and work with de Bruijn representations (section{~}\ref{usingNaPa}). Finally, we extend the logical relation so as demonstrate the soundness of the extended library, and we study the meaning of some of the {``}free theorems{''} that can be obtained about client code (section{~}\ref{napaRel}).% \subsection{The bare approach\label{bareDeBruijn}} % %paragraphName: description of bare The {``}bare{''} approach relies solely on natural numbers. To make things concrete, here is an example of its use. This is our running example, namely a representation of the terms of the untyped $ \lambda $-calculus{:}% {\nopagebreak } % %code: % %comment: data Tmᴮ : Set where % V : (x : ℕ) → Tmᴮ % _·_ : (t u : Tmᴮ) → Tmᴮ % ƛ : (t : Tmᴮ) → Tmᴮ % Let : (t u : Tmᴮ) → Tmᴮ % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}u\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}u\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: in bare, types are weak From the point of view of the binding structure, it is quite striking that there is no visible difference between the constructors of this data type. It is completely up to the programmer to manage the fact that{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}} and{~}\texttt{Let} introduce a new variable. This is particularly worrying in the case of{~}\texttt{Let}, where we have no clue that there should be a difference of treatment between the arguments.% % %paragraphName: appTmᴮ in bare Here is how one might build the $ \lambda $-term for function application, namely{~}\texttt{$ \lambda $f.$ \lambda $x.f{~}x}.% {\nopagebreak } % %code: % %comment: appTmᴮ : Tmᴮ %appTmᴮ = ƛ (ƛ (V 1 · V 0)) % ~\\~\vphantom{$\{$}\texttt{appTm\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{B}}{\nopagebreak \newline% }\vphantom{$\{$}appTm\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}0\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: bare expressiveness The main advantages of the {``}bare{''} approach are its simplicity and its expressiveness. Expressiveness is in a sense maximal, since no restriction is put on the usage of variables.% \subsection{The \texttt{Maybe} approach\label{nestedS}} % %paragraphName: Tmᴹ The \texttt{Maybe} approach, also known as the nested data type approach{~}\cite{bellegarde-94,bird-paterson-99,altenkirch-reus-99}, is a first step towards better describing the binding structure of terms, and enforcing stronger guarantees about code that manipulates terms. Let us start with the definition of the type of $ \lambda $-terms with this approach{:}% {\nopagebreak } % %code: % %comment: data Tmᴹ (A : Set) : Set where % V : (x : A) → Tmᴹ A % _·_ : (t u : Tmᴹ A) → Tmᴹ A % ƛ : (t : Tmᴹ (Maybe A)) → Tmᴹ A % Let : (t : Tmᴹ A) (u : Tmᴹ (Maybe A)) → Tmᴹ A % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}A\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Maybe\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}u\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Maybe\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: explaining Tmᴹ Three points must be noticed. First, the type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}}\index{Code!\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}}} is parameterized with a type{~}\texttt{A}, so one can look at it as a kind of container. Second, the data constructor{~}\texttt{V}\index{Code!\texttt{V}} does not carry a raw de Bruijn index, which would have type{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}}, but a value of type{~}\texttt{A}. Last, but not least, the data constructor{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}\index{Code!\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}} carries a term whose index is not{~}\texttt{A} but{~}\texttt{Maybe\makebox[1.22ex][c]{{~}}A}.% % %paragraphName: nested/non-regular The last point makes the type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}} a nested data type, also known as a non-regular data type. This has the consequence that polymorphic recursion is required in order to define recursive functions over such a type.% % %paragraphName: adequacy of Maybe To understand why this is an adequate representation of $ \lambda $-terms, let us examine the meaning of{~}\texttt{Maybe}. If types are viewed as sets of values, then the type transformer{~}\texttt{Maybe} can be viewed as a function that takes a set and produces a set with one extra element. Thus, each time we cross a{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}, we add one element to the set of variables that can be referred to. This captures the fact that we are introducing a variable.% % %paragraphName: appTmᴹ in Maybe To better see the difference with the previous approach, let us look again the $ \lambda $-term for function application{:}% {\nopagebreak } % %code: % %comment: appTmᴹ : Tmᴹ ⊥ %appTmᴹ = ƛ (ƛ (V (just nothing) · V nothing)) % ~\\~\vphantom{$\{$}\texttt{appTm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \bot $}{\nopagebreak \newline% }\vphantom{$\{$}appTm\makebox[0.61ex][l]{\textsuperscript{M}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}just\mbox{\hspace{0.50em}}nothing\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}nothing\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⊥ in Maybe The use of the empty type{~}\texttt{\makebox[1.22ex][c]{$ \bot $}} reflects the fact that the term{~}\texttt{appTm\makebox[0.61ex][l]{\textsuperscript{M}}}\index{Code!\texttt{appTm\makebox[0.61ex][l]{\textsuperscript{M}}}} is closed. Stating such a property as part of the type was impossible in the bare approach; it would have to be stated as a separate assertion.% \subsection{The \texttt{Fin} approach\label{finS}} % %paragraphName: Fin approach description Another approach, which has been described and used by several authors{~}\cite{altenkirch-93,mcbride-mckinna-04}, is to index the type of terms with a natural number. This number represents a bound on the free variables that are allowed to occur in a term.% % %paragraphName: Fin type description This approach relies on the type{~}\texttt{Fin\makebox[1.22ex][c]{{~}}n}, whose definition, found in \textsc{Agda}{'}s standard library, is the following{:}% {\nopagebreak } % %code: % %comment: data Fin : ℕ → Set where % zero : {n : ℕ} → Fin (suc n) % suc : {n : ℕ} (i : Fin n) → Fin (suc n) % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Fin\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}zero\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}n\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Fin\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}suc\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}n\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}i\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Fin\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Fin\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Fin type description (continued) The type \texttt{Fin\makebox[1.22ex][c]{{~}}n} is isomorphic to the set of the natural numbers that are less than{~}\texttt{n}. More generally, it is isomorphic to every set of exactly \texttt{n} elements. This explains the name \texttt{Fin}, which stands for {``}finite{''}.% % %paragraphName: Tmᶠ In this approach, the inductive type of $ \lambda $-terms is defined as follows{:}% {\nopagebreak } % %code: % %comment: data Tmᶠ n : Set where % V : (x : Fin n) → Tmᶠ n % _·_ : (t u : Tmᶠ n) → Tmᶠ n % ƛ : (t : Tmᶠ (suc n)) → Tmᶠ n % Let : (t : Tmᶠ n) (u : Tmᶠ (suc n)) → Tmᶠ n % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Fin\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}u\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Tmᶠ (continued) The data constructor{~}\texttt{V} carries a de Bruijn index, and requires that this index be less than \texttt{n}. The data constructor{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}\index{Code!\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}}, which binds a new variable, increments the index \texttt{n}, thus making one more index available.% % %paragraphName: Tm 0 in Fin Like the \texttt{Maybe} approach, this representation helps enforce certain well-formedness properties. For instance, \texttt{Tm\makebox[0.61ex][l]{\textsuperscript{f}}\makebox[1.22ex][c]{{~}}0} is the type of closed $ \lambda $-terms.% % %paragraphName: appTm in Fin Here is the $ \lambda $-term for application in this approach{:}% {\nopagebreak } % %code: % %comment: appTmᶠ : Tmᶠ 0 %appTmᶠ = ƛ (ƛ (V (suc zero) · V zero)) % ~\\~\vphantom{$\{$}\texttt{appTm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}0{\nopagebreak \newline% }\vphantom{$\{$}appTm\makebox[0.61ex][l]{\textsuperscript{f}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}zero\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}zero\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Fin/Maybe connection One can easily recognize a similarity between the{~}\texttt{Maybe} and \texttt{Fin} approaches. Indeed, the type \texttt{Fin\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}suc\makebox[1.22ex][c]{{~}}n\makebox[1.22ex][r]{$ {)} $}} has exactly one more element than the type{~}\texttt{Fin\makebox[1.22ex][c]{{~}}n}. However, these approaches are not equivalent, for at least two reasons. The{~}\texttt{Maybe} approach can use any type \texttt{A} to represent the free variables of a term. This allows terms to be viewed as containers, and allows defining substitution as the composition of \texttt{mapTm\makebox[1.22ex][c]{{~}}{:}}{ }\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}A\makebox[1.22ex][c]{{~}}B\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}A\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}B\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}\makebox[1.22ex][c]{{~}}B} and \texttt{joinTm\makebox[1.22ex][c]{{~}}{:}}{ }\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}A\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{M}}\makebox[1.22ex][c]{{~}}A\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}\makebox[1.22ex][c]{{~}}A}{~}\cite{bellegarde-94,bird-paterson-99,altenkirch-reus-99}. The{~}\texttt{Fin} approach has the advantage of being more concrete, hence simpler. However, this apparent simplicity comes at a cost. In the \texttt{Maybe} approach, a function that examines a term of type \texttt{Tm\makebox[0.61ex][l]{\textsuperscript{M}}\makebox[1.22ex][c]{{~}}A} and that is polymorphic in \texttt{A} comes with a strong {``}free theorem{''}, which guarantees that this function views the free variables as abstract, so that (for instance) a free variable and a bound variable cannot be mistakenly compared. In the \texttt{Fin} approach, in contrast, all variables are represented as integer indices, regardless of whether they are free or bound, so that confusion is possible.% \section{The \textsc{NomPa} interface and implementation (de Bruijn fragment)\label{napaS}} % %paragraphName: figure \begin{figure}[] \begin{flushleft} % %code: {\noindent}% %comment: -- Constructing worlds %_+1 : World → World % %_↑1 : World → World %α ↑1 = 0 ᴮ ◅ (α +1) % %-- Name arithmetic %addᴺ : ∀ {α} k → Name α % → Name (α +ᵂ k) %subtractᴺ : ∀ {α} k → Name (α +ᵂ k) % → Name α %cmpᴺ : ∀ {α} ℓ → Name (α ↑ ℓ) % → Name (ø ↑ ℓ) ⊎ Name (α +ᵂ ℓ) % %syntax addᴺ k x = x +ᴺ k %syntax subtractᴺ k x = x ∸ᴺ k %syntax cmpᴺ ℓ x = x <ᴺ ℓ % %-- World inclusion %⊆-ø+1 : ø +1 ⊆ ø %⊆-↑1-↑1 : ∀{α β}→ α ⊆ β ↔ α ↑1 ⊆ β ↑1 %⊆-+1-+1 : ∀{α β}→ α ⊆ β ↔ α +1 ⊆ β +1 %⊆-+1-↑1 : ∀{α}→ α +1 ⊆ α ↑1 % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}Constructing\mbox{\hspace{0.50em}}worlds{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}+1\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}arithmetic{\nopagebreak \newline% }\vphantom{$\{$}add\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{3em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}k\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{7.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}subtract\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}k\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{7.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}cmp\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{3em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{7.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{\ensuremath{\uplus}}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}syntax\mbox{\hspace{0.50em}}add\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{3em}}k\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}k{\nopagebreak \newline% }\vphantom{$\{$}syntax\mbox{\hspace{0.50em}}subtract\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}k{\nopagebreak \newline% }\vphantom{$\{$}syntax\mbox{\hspace{0.50em}}cmp\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{3em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}inclusion{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}+1\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}+1\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \uparrow $}1-\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \leftrightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \subseteq $}-+1-+1\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \leftrightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}+1{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.83ex][c]{$ \subseteq $}-+1-\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1{\nopagebreak \newline% }\vphantom{$\{$}}% \end{flushleft} \caption{The \textsc{NomPa} interface (de Bruijn fragment)\label{napaIfaceF}} \end{figure}% % %paragraphName: our contribution We wish to offer an approach to {``}well-typed de Bruijn indices{''} that exploits parametricity to offer strong guarantees of well-behavedness, like the \texttt{Maybe} approach, and at the same time offers the ability to work with natural integer indices and to perform low-level arithmetic operations, like the \texttt{Fin} approach.% % %paragraphName: specialized operations added to the current interface It turns out that we can do this by \emph{extending} the library that we have presented so far with support for arithmetic operations over worlds and over names. We need not throw anything away. This is in contrast with our first conference paper{~}\cite{pouillard-pottier-10}, where we presented two distinct implementations of a common interface. Here, there is no need to make a monolithic choice between the nominal style and de Bruijn{'}s style. The library simultaneously supports both styles.% % %paragraphName: reusing nompa Thus, everything that we have built up to this point remains valid and useful. The types and operations of figure \ref{nompaIface} remain available to the client, and their implementation is unchanged. The new types and operations in figure \ref{napaIfaceF} come in addition to those of figure \ref{nompaIface}.% \subsection{New operations on worlds} % %paragraphName: λ-abstraction in 2 parts What must we add to the library in order to enable working with de Bruijn indices? First and foremost, we must be able to describe how the current world is affected by the introduction of a new name. In the nominal setting, we introduced the operation{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}} for this purpose. If one thinks of worlds as sets of names, then{~}\texttt{b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} is the set obtained by adding the binder \texttt{b} to the set \texttt{\makebox[1.22ex][c]{$ \alpha $}}. In the de Bruijn setting, things are different. At a binding construct, such as \texttt{$ \lambda $}, two things occur{:} the name 0 is introduced and considered a {``}new{''} name, while all previous names are incremented by one. Thus, the key feature of this approach is that descending under a new binder changes the manner in which previous binders are referred to. % % %paragraphName: +1 In order to account for this phenomenon, we introduce a new operation on worlds, written{~}\texttt{\makebox[1.22ex][c]{\_{}}+1}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}+1}} (figure \ref{napaIfaceF}). It is a translation operation{:} if \texttt{\makebox[1.22ex][c]{$ \alpha $}} is viewed as a set of names, then \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+1} is the set obtained by adding one to each element of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}.% % %paragraphName: Tmᴰ first attempt This single extension of the library allows us to build name abstractions in de Bruijn style. Here is our running example, a representation of the syntax of the untyped $ \lambda $-calculus, this time in de Bruijn style{:}% {\nopagebreak } % %code: % %comment: data Tmᴰ α : Set where % V : Name α → Tmᴰ α % _·_ : Tmᴰ α → Tmᴰ α → Tmᴰ α % ƛ : Tmᴰ (0 ᴮ ◅ (α +1)) → Tmᴰ α % Let : Tmᴰ α → Tmᴰ (0 ᴮ ◅ (α +1)) → Tmᴰ α % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Tmᴰ.ƛ/_↑1 Just as in the nominal setting, the type of terms is indexed with a world. The only difference between{~}\texttt{Tm} and{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}} is in the representation of the binding constructs. In the nominal version, the data constructor{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}} carries a binder{~}\texttt{b} and a subterm where{~}\texttt{b} is considered bound. Here, in contrast, \texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}} carries just a subterm, where the binder{~}\texttt{0\makebox[1.22ex][c]{{~}}\makebox[0.61ex][l]{\textsuperscript{B}}} is considered bound, and where all previous binders are translated up by one.% % %paragraphName: shift world Because the operation of incrementing by one and introducing{~}\texttt{0\makebox[1.22ex][c]{{~}}\makebox[0.61ex][l]{\textsuperscript{B}}} is idiomatic, it deserves a concise notation, which we now define (see also figure{~}\ref{napaIfaceF}){:}% {\nopagebreak } % %code: % %comment: _↑1 : World → World %α ↑1 = 0 ᴮ ◅ (α +1) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _↑1/Tmᴰ We refer to the operation{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1}} as {``}shifting{''} a world. The inductive definition of the type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}} can now be reformulated in a more concise and transparent manner{:}% {\nopagebreak } % %code: % %comment: data Tmᴰ α : Set where % V : Name α → Tmᴰ α % _·_ : Tmᴰ α → Tmᴰ α → Tmᴰ α % ƛ : Tmᴰ (α ↑1) → Tmᴰ α % Let : Tmᴰ α → Tmᴰ (α ↑1) → Tmᴰ α % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}V\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}Let\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Maybe/Fin If one replaces{~}\texttt{World} by{~}\texttt{Set}, \texttt{Name} by the identity, and \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} by{~}\texttt{Maybe}, then one recovers the nested data type approach described in section{~}\ref{nestedS}. Similarly, if one replaces{~}\texttt{World} by{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}}, \texttt{Name} by{~}\texttt{Fin}, and{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} by{~}\texttt{suc}, then one recovers the{~}\texttt{Fin} approach of section{~}\ref{finS}. In our approach,{~}\texttt{World}, \texttt{Name}, and \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} are abstract, which allows us to obtain stronger {``}free theorems{''}. Nevertheless, as we will see very soon (section \ref{newOpNameS}), we are still able to offer low-level arithmetic operations on names.% % %paragraphName: _+1 implem Our internal representation of worlds as lists of Boolean values (section{~}\ref{nompaImplem}) makes it easy to implement{~}\texttt{\makebox[1.22ex][c]{\_{}}+1}.% {\nopagebreak } % %code: % %comment: _+1 : World → World %α +1 = false ∷ α % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}+1\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}World{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}false\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _↑1 implem The operation{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} was defined above in terms of {~}\texttt{\makebox[1.22ex][c]{\_{}}+1} and{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\_{}}}. If we expand this definition, we find that \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1} is just \texttt{true\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{{:}{:}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}.% % %paragraphName: Generalizing ↑1 and +1 The definitions of the {``}one-step{''} operations{~}\texttt{\makebox[1.22ex][c]{\_{}}+1} and{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} are extended to {``}any number of steps{''} to produce the operations{~}\texttt{\makebox[1.22ex][c]{\_{}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{\_{}}}} and{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\_{}}}}, which have type{~}\texttt{World\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{World}. The world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k} is{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+1\makebox[2.44ex][l]{$ \ldots $}+1}, where \texttt{\makebox[1.22ex][c]{\_{}}+1} is iterated{~}\texttt{k} times. The world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k} is \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[2.44ex][l]{$ \ldots $}\makebox[1.22ex][c]{$ \uparrow $}1}, where \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} is iterated{~}\texttt{k} times.% % %paragraphName: _+_, _↑_ distinction is new To the best of our knowledge, the distinction between translation{~}(\texttt{\makebox[1.22ex][c]{\_{}}+1}) and shifting{~}(\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1}) at the level of worlds has never been investigated. We argue in section{~}\ref{strengthThm} that this distinction can be important. By exploiting{~}(\texttt{\makebox[1.22ex][c]{\_{}}+1}) instead of{~}(\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1}) where appropriate, one can express more precise types, with which stronger {``}free theorems{''} are associated. Conversely, if one uses{~}(\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1}) everywhere, one must declare coarser types, and one runs a greater risk that intuitively incorrect code is considered well-typed.% \subsection{New operations on names\label{newOpNameS}} % %paragraphName: intro We extend the library with a small number of new operations on names. These operations allow performing low-level arithmetic on de Bruijn indices. They receive abstract types that describe their effect in terms of worlds.% % %paragraphName: zeroᴺ We need to be able to construct the name 0. The nominal fragment of the library offers the constant \texttt{zero\makebox[0.61ex][l]{\textsuperscript{B}}}, which has type \texttt{Binder}. When working in de Bruijn style, we never use the type \texttt{Binder}, so we prefer to define a constant{~}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{zero\makebox[0.61ex][l]{\textsuperscript{N}}}} whose type is an instance of \texttt{Name}. This constant inhabits every world that has been shifted by one. It can be defined in terms of the existing interface, so it does not technically represent an extension of the library{:}% {\nopagebreak } % %code: % %comment: zeroᴺ : ∀ {α} → Name (α ↑1) %zeroᴺ = nameᴮ (0 ᴮ) % ~\\~\vphantom{$\{$}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}zero\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}name\makebox[0.61ex][l]{\textsuperscript{B}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: figure \begin{figure}[] \begin{flushleft} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \path node (NmOpK){\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}}}; \path node (NmO)[below of=NmOpK]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}}}; \path node (Bot)[right of=NmO,right=1cm of NmO]{\texttt{\makebox[1.22ex][c]{$ \bot $}}}; \path node (NmA)[below of=NmO]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}}; \path node (NmApK)[below of=NmA]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}}}; \path node (NmAsK)[below of=NmApK]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}}}; \path node (NmOsK)[below of=NmAsK]{\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}}}; \path node (FinK)[right of=NmOsK,right=1cm of NmOsK]{\texttt{Fin\makebox[1.22ex][c]{{~}}k}}; \path[->] (NmOpK) edge node [left]{\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\_{}}}}(NmO); \path[->] (NmO) edge node [below]{\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}}(Bot); \path[->] (NmO) edge node [left]{\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{$ \alpha $}}}(NmA); \path[->] (NmA) edge[bend right] node [left]{\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}k}}(NmApK); \path[->] (NmApK) edge[bend right] node [right]{\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}k}}(NmA); \path[->] (NmApK) edge[bend right] node [left]{\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\_{}}}}(NmAsK); \path[->] (NmAsK) edge[bend right] node [right]{ \texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}}{~}(\textit{if} \texttt{\makebox[1.22ex][c]{$ \geq $}k})}(NmApK); \path[->] (NmAsK) edge[bend left] node [right]{ \texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}}{~}(\textit{if} \texttt{\makebox[1.22ex][c]{\textless{}}k})}(NmOsK); \path[->] (NmOsK) edge[bend left] node [left]{\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\_{}}}}(NmAsK); \path[->] (NmOsK.north east) edge[bend left] node [above]{}(FinK.north west); \path[<-] (NmOsK.south east) edge[bend right] node [below]{}(FinK.south west); \end{tikzpicture} \end{center}% \end{flushleft} \caption{The typical types of names\label{napaOpsDiagF}} \end{figure}% % %paragraphName: core operations descriptions We introduce three new operations on names, whose signatures are given in figure{~}\ref{napaIfaceF}. These operations are addition, subtraction, and comparison.% % %paragraphName: addition and subtraction One can add a constant to a name using{~}\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}}} and perform the opposite operation using \texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}}}. Thanks to the world translation operation{~}\texttt{\makebox[1.22ex][c]{\_{}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{\_{}}}}{~}, the types assigned to these operations are as precise as possible. Because the domain of the subtraction operation is \texttt{Name}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}}{ }\texttt{+\makebox[0.61ex][l]{\textsuperscript{W}}}{ }\texttt{k\makebox[1.22ex][r]{$ {)} $}}, this operation is a total function, and is the inverse of{~}\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}}. Thus, the types{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} and{~}\texttt{Name}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}} are effectively isomorphic.% % %paragraphName: the comparison function When one writes a recursive function that descends into a term in de Bruijn style, one usually carries a natural number{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} that represents the number of binders that have been entered. In such a situation, a de Bruijn index that is strictly less than{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} refers to one of the binders that was entered on the way down{:} we say that such a name is {``}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound{''}. A de Bruijn index that is greater than or equal to{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} refers to a free name of the term that is being examined{:} we say that such a name is {``}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free{''}. It is necessary to be able to distinguish between these cases. For this purpose, we introduce the comparison operation{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}}. This operation compares a natural number{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} and a name{~}\texttt{x}. The name{~}\texttt{x} is assumed to inhabit the world \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}. This world is the disjoint union of the world{~}\texttt{\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}, which represents the entire interval {[}0,{~}\ensuremath{\ell}), and of the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}, which represents a certain set of names all of which are greater than or equal to{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}. The codomain of{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}} reflects this disjoint union. The comparison{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{{~}}x} produces a disjoint sum whose tag (\texttt{inj\makebox[0.61ex][l]{$ _{{1}} $}} or \texttt{inj\makebox[0.61ex][l]{$ _{{2}} $}}) encodes the Boolean outcome of the comparison and whose payload is the name{~}\texttt{x} at a refined type. Like \texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}}, this operation combines a dynamic test and a static type refinement operation.% % %paragraphName: figure Figure{~}\ref{napaOpsDiagF} depicts several types of names and how our operations relate them. Let us begin at the bottom. A name of type{~}\texttt{Name}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}} is definitely \texttt{k}-bound{:} it is a member of the interval{~}{[}0,{~}k). The type{~}\texttt{Fin\makebox[1.22ex][c]{{~}}k} also represents this interval{:} \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}} and{~}\texttt{Fin\makebox[1.22ex][c]{{~}}k} are isomorphic types. Higher up, we find a type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}} of names that may be \texttt{k}-bound or \texttt{k}-free. A dynamic test (permitted by the operation{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}}}) allows telling whether such a name is{~}\texttt{k}-bound or \texttt{k}-free, and (via a type refinement) sends this name into either \texttt{Name}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}}, one level down, or \texttt{Name}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}}, one level up. A name of type \texttt{Name}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}} is definitely \texttt{k}-free. As noted earlier, this type is isomorphic to \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. Finally, in the top part of the diagram, we find empty types. The type \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}} is empty, so it is a subset of \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} and more generally of the empty type \texttt{\makebox[1.22ex][c]{$ \bot $}}. The type \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}} is also empty, because the world inclusion rule \texttt{\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}+1} (to be introduced shortly) states that the world \texttt{\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}+1} is empty.% % %paragraphName: NaPa vs Fin The isomorphism between{~}\texttt{Fin\makebox[1.22ex][c]{{~}}n} and{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}n\makebox[1.22ex][r]{$ {)} $}} means that every program that uses the{~}\texttt{Fin}\index{Code!\texttt{Fin}} approach can be translated into our system. This means that our approach is at least as expressive as the{~}\texttt{Fin} approach. It also means that our approach is not inherently safer than the{~}\texttt{Fin} approach. In our approach, stronger guarantees than in the{~}\texttt{Fin} approach can be obtained if one decides to use more precise types than{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}n\makebox[1.22ex][r]{$ {)} $}}. We come back to this point in section{~}\ref{strengthThm}.% \subsection{New world inclusion rules} % %paragraphName: ⊆ rules We extend the world inclusion relation with a set of new rules, which appear in figure{~}\ref{napaIfaceF}. These rules state that the world{~}\texttt{\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}+1} is empty, that the operations{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} and{~}\texttt{\makebox[1.22ex][c]{\_{}}+1} preserve world inclusion (both ways), and that{~}\texttt{\makebox[1.22ex][c]{\_{}}+1} can be weakened to{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1}. The last rule accounts for the fact that{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1} is the disjoint union of the singleton set{~}\{{}0\}{} and of the world \texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+1\makebox[1.22ex][r]{$ {)} $}} and is thus a proper superset of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+1}.% % %paragraphName: forgetting to shift It is worth noting that the candidate rule \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1} is not valid. This follows from the fact that \texttt{\makebox[1.22ex][c]{$ \alpha $}} denotes an arbitrary set of names, as opposed to, say, an interval of the form {[}0,{~}n). As a result, in a situation where \texttt{\makebox[1.22ex][c]{$ \alpha $}} is an abstract world, the only way of transporting a name from \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} to \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}} is to add one to it. In contrast, in the \texttt{Fin} approach, the type \texttt{Fin\makebox[1.22ex][c]{{~}}n} is a subset of the type \texttt{Fin\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}n\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}1\makebox[1.22ex][r]{$ {)} $}}, so there are two ways of transporting a name from \texttt{Fin\makebox[1.22ex][c]{{~}}n} to \texttt{Fin\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}n\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}1\makebox[1.22ex][r]{$ {)} $}}{:} one is the identity, the other is the addition of one. It is in principle possible to mistakenly use the former in place of the latter{:} this amounts to {``}omitting to shift{''} a de Bruijn index. In our approach, provided the programmer was wise enough to assign a world-polymorphic type to the function where the mistake lies, this results in an ill-typed program.% \section{Programming on top of \textsc{NomPa} (de Bruijn fragment)\label{usingNaPa}} % %paragraphName: summary We now illustrate how the library allows working with terms in de Bruijn style. We show how to build terms, how to write recursive functions over terms, and how to build a generic term traversal function whose instances include shifting and capture-avoiding substitution.% \subsection{Some convenience functions\label{convenienceS}} % %paragraphName: external layer A number of useful functions can be built on top of the interface, that is, without access to the library{'}s internal details. In practice, these functions can be shipped with the library, as part of an {``}external library layer{''}.% % %paragraphName: convenience functions description The function \texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}}} is just{~}\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}1}. The function{~}\texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}}\index{Code!\texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}}} is a variant of \texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}}} that includes a coercion from{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+1} to{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1}. The function \texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}}\index{Code!\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}}} is a variant of{~}\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}} that includes a coercion from{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k} to{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k}.% {\nopagebreak } % %code: % %comment: sucᴺ : ∀ {α} → Name α → Name (α +1) %sucᴺ = addᴺ 1 % ~\\~\vphantom{$\{$}\texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+1\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}suc\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}add\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}1{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: sucᴺ↑ : ∀ {α} → Name α → Name (α ↑1) %sucᴺ↑ = coerceᴺ ⊆-+1↑1 ∘ sucᴺ % \vphantom{$\{$}\texttt{suc\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}suc\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-+1\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}suc\makebox[0.61ex][l]{\textsuperscript{N}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: addᴺ↑ : ∀ {α} ℓ → Name α → Name (α ↑ ℓ) %addᴺ↑ ℓ = coerceᴺ (⊆-+-↑ ℓ) ∘ addᴺ ℓ % \vphantom{$\{$}\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-+-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}add\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: convenience functions description (continued) The function{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][l]{\textsuperscript{N}}}} turns a natural number, say{~}\texttt{n}, into a name. This name inhabits any world that has been shifted at least{~}\texttt{n\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}1} times.% {\nopagebreak } % %code: % %comment: _ᴺ : ∀ {α} n → Name (α ↑ suc n) %_ᴺ {α} n = zeroᴺ +ᴺ n % ⟨-because α ↑1 +ᵂ n ⊆⟨ ⊆-+-↑ n ⟩ % α ↑1 ↑ n ⊆⟨ ⊆-exch-↑-↑ 1 n ⟩ % α ↑ suc n ∎ -⟩ % where open ⊆-Reasoning % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}suc\mbox{\hspace{0.50em}}n\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}zero\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}n{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-+-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{1em}}n\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-exch-\makebox[1.22ex][c]{$ \uparrow $}-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}suc\mbox{\hspace{0.50em}}n\mbox{\hspace{0.50em}}\ensuremath{{\scriptstyle \blacksquare}}\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{0.50em}}where\mbox{\hspace{0.50em}}open\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-Reasoning{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: subtractᴺ? Like{~}\texttt{cmp}, the function{~}\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}?}\index{Code!\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}?}} tests whether a name{~}\texttt{x} is \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound or \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free. If \texttt{x} is \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound, the operation fails; otherwise, it returns the name{~}\texttt{x\makebox[1.22ex][c]{{~}}-\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}, which can be considered as {``}a version of the name \texttt{x} that has been exported through \ensuremath{\ell} binders{''}. This function forms the base case of \texttt{subtractTm\makebox[0.61ex][l]{\textsuperscript{D}}?}, the user-defined function that {``}exports{''} a term, which is presented later on (section \ref{napaTraversal}).% {\nopagebreak } % %code: % %comment: subtractᴺ? : ∀ {α} ℓ → Name (α ↑ ℓ) →? Name α %subtractᴺ? ℓ x % with x <ᴺ ℓ %... | inj₁ _ = nothing %... | inj₂ x′ = just (x′ ∸ᴺ ℓ) % ~\\~\vphantom{$\{$}\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}subtract\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}with\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{1em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}nothing{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{1em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}just\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: subtractᴺ? (continued) The function{~}\texttt{pred\makebox[0.61ex][l]{\textsuperscript{N}}?}\index{Code!\texttt{pred\makebox[0.61ex][l]{\textsuperscript{N}}?}} is a simple specialization of{~}\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}?}.% {\nopagebreak } % %code: % %comment: predᴺ? : ∀ {α} → Name (α ↑1) →? Name α %predᴺ? = subtractᴺ? 1 % ~\\~\vphantom{$\{$}\texttt{pred\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}pred\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}subtract\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}1{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: subtractWithᴺ On top of{~}\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}?}, we build a convenient eliminator for names. It is simply the elimination of the result of{~}\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}?}.% {\nopagebreak } % %code: % %comment: subtractWithᴺ : ∀ {α A} ℓ → A → (Name α → A) → Name (α ↑ ℓ) → A %subtractWithᴺ v f = maybe f v ∘′ subtractᴺ? % ~\\~\vphantom{$\{$}\texttt{subtractWith\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}A{\nopagebreak \newline% }\vphantom{$\{$}subtractWith\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}maybe\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}$ \circ $\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}subtract\makebox[0.61ex][l]{\textsuperscript{N}}?{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: shiftName The function{~}\texttt{shiftName\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][c]{{~}}pf}\index{Code!\texttt{shiftName}} tests whether its argument, a name \texttt{x}, is \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound or \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free. If the former, then \texttt{x} is returned unmodified. If the latter, then \texttt{x\makebox[1.22ex][c]{{~}}+\makebox[1.22ex][c]{{~}}k} is returned. In other words, this function behaves as the identity at \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound names and as a translation at \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free names. If one takes \texttt{\makebox[1.22ex][c]{$ \beta $}} to be \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k}, one finds that this function admits the type \texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}}, which reflects the behavior that was just described. More generally, for greater flexibility, we allow \texttt{\makebox[1.22ex][c]{$ \beta $}} to be a superset of \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k}, and we build a coercion of \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{{~}}k} to{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} into the definition of{~}\texttt{shiftName}.% {\nopagebreak } % %code: % %comment: shiftName : ∀ {α} ℓ k → (α +ᵂ k) ⊆ β → ((α ↑ ℓ) →ᴺ (β ↑ ℓ)) %shiftName ℓ k pf x % with x <ᴺ ℓ %... | inj₁ x′ = x′ ⟨-because pf₁ -⟩ -- x is ℓ-bound %... | inj₂ x′ = x′ +ᴺ k ⟨-because pf₂ -⟩ -- x is ℓ-free % where % pf₁ = ⊆-cong-↑ ⊆-ø ℓ % pf₂ = ⊆-trans (⊆-exch-+-+ ⊆-refl ℓ k) % (⊆-ctx-+↑ pf ℓ) % ~\\~\vphantom{$\{$}\texttt{shiftName\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}shiftName\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}with\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{1.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}pf\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}-bound{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}pf\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}-free{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}pf\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-cong-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}pf\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-trans\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-exch-+-+\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-refl\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{8em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-ctx-+\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: protect↑ The function{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}\index{Code!\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}} shifts a name transformer. If{~}\texttt{f} is a function of names to names, then{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{{~}}f} is also a function of names to names, which behaves as the identity at \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound names and behaves like \texttt{f} at \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free names. More precisely, its behavior at an \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free name{~}\texttt{x} is to subtract{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} from{~}\texttt{x}, apply{~}\texttt{f}, then add{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} back to the result.% {\nopagebreak } % %code: % %comment: protect↑ : ∀ {α β} ℓ → (α →ᴺ β) → ((α ↑ ℓ) →ᴺ (β ↑ ℓ)) %protect↑ ℓ f x % with x <ᴺ ℓ %... | inj₁ x′ = x′ ⟨-because ⊆-cong-↑ ⊆-ø ℓ -⟩ %... | inj₂ x′ = f (x′ ∸ᴺ ℓ) +ᴺ ℓ ⟨-because ⊆-+-↑ ℓ -⟩ % ~\\~\vphantom{$\{$}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}protect\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{0.50em}}with\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{8.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-cong-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{2em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-+-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: shiftName′ The reader may notice that, since \texttt{shiftName} behaves as the identity at \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound names, one could define it as an instance of \texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}. That is, one could give the following alternative definition{:}% {\nopagebreak } % %code: % %comment: shiftName′ : ∀ {α β} ℓ k → (α +ᵂ k) ⊆ β → ((α ↑ ℓ) →ᴺ (β ↑ ℓ)) %shiftName′ ℓ k pf = protect↑ (coerceᴺ pf ∘ addᴺ k) ℓ % ~\\~\vphantom{$\{$}\texttt{shiftName\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}shiftName\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}protect\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}add\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: shiftName′ (continued) This version is fine, but slightly less efficient than{~}\texttt{shiftName}, which, in the case where \texttt{x} is \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free, avoids subtracting{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} and adding{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} back.% \subsection{Building terms} % %paragraphName: bulding terms description Building terms in de Bruijn style is just as easy with our library as it is in the bare de Bruijn index approach. The structure is exactly the same. Natural numbers are converted to variables using{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][l]{\textsuperscript{N}}}. Below, we show how to construct representations of the identity function (\texttt{idTm\makebox[0.61ex][l]{\textsuperscript{D}}}\index{Code!\texttt{idTm\makebox[0.61ex][l]{\textsuperscript{D}}}}), of the application operator (\texttt{appTm\makebox[0.61ex][l]{\textsuperscript{D}}}\index{Code!\texttt{appTm\makebox[0.61ex][l]{\textsuperscript{D}}}}), of the composition function (\texttt{compTm\makebox[0.61ex][l]{\textsuperscript{D}}}\index{Code!\texttt{compTm\makebox[0.61ex][l]{\textsuperscript{D}}}}), and of the Church encodings. of true and false (\texttt{trueTm\makebox[0.61ex][l]{\textsuperscript{D}}}\index{Code!\texttt{trueTm\makebox[0.61ex][l]{\textsuperscript{D}}}} and \texttt{falseTm\makebox[0.61ex][l]{\textsuperscript{D}}}\index{Code!\texttt{falseTm\makebox[0.61ex][l]{\textsuperscript{D}}}}).% {\nopagebreak } % %code: % %comment: idTmᴰ : ∀ {α} → Tmᴰ α %appTmᴰ : ∀ {α} → Tmᴰ α %compTmᴰ : ∀ {α} → Tmᴰ α %trueTmᴰ : ∀ {α} → Tmᴰ α %falseTmᴰ : ∀ {α} → Tmᴰ α % %idTmᴰ = ƛ(V (0 ᴺ)) %appTmᴰ = ƛ(ƛ(V (1 ᴺ) · V (0 ᴺ))) %compTmᴰ = ƛ(ƛ(ƛ(V (2 ᴺ)) · (V (1 ᴺ) · V (0 ᴺ)))) % %trueTmᴰ = ƛ(ƛ(V (1 ᴺ))) %falseTmᴰ = ƛ(ƛ(V (0 ᴺ))) % ~\\~\vphantom{$\{$}\texttt{idTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}appTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{1.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}compTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}trueTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}falseTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}idTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{2em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}appTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}1\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}compTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}2\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}1\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}trueTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}1\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}falseTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}0\mbox{\hspace{0.50em}}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Example{:} computing free variables} % %paragraphName: fvᴰ description As an example of a function that is defined by induction over a term, we again show how to compute a list of the free variables of a term. The overall structure of the code is the same as in the nominal setting (section \ref{computingFreeVarS}). As before, in the case of a binding construct, such as{~}\texttt{\makebox[1.22ex][c]{{\nptextcrlambda}}}, we must remove the bound name from the list of variables produced by the recursive call. In this nameless representation, this means that we must remove from the list every occurrence of{~}0 and we must subtract{~}1 to every other name. This is done by the auxiliary function{~}\texttt{rm\makebox[0.61ex][l]{$ _{{0}} $}}\index{Code!\texttt{rm\makebox[0.61ex][l]{$ _{{0}} $}}}, which applies{~}\texttt{pred\makebox[0.61ex][l]{\textsuperscript{N}}?} to each element of the list and merges the results.% {\nopagebreak } % %code: % %comment: rm₀ : ∀ {α} → List (Name (α ↑1)) → List (Name α) %rm₀ [] = [] %rm₀ (x ∷ xs) with predᴺ? x %... | just x' = x' ∷ rm₀ xs %... | nothing = rm₀ xs % ~\\~\vphantom{$\{$}\texttt{rm\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}rm\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}{[}{]}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}{[}{]}{\nopagebreak \newline% }\vphantom{$\{$}rm\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}xs\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}with\mbox{\hspace{0.50em}}pred\makebox[0.61ex][l]{\textsuperscript{N}}?\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{6em}}\textbar{}\mbox{\hspace{1em}}just\mbox{\hspace{0.50em}}x{'}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}x{'}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{:}{:}}\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}xs{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{6em}}\textbar{}\mbox{\hspace{1em}}nothing\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}xs{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: fvᴰ : ∀ {α} → Tmᴰ α → List (Name α) %fvᴰ (V x) = [ x ] %fvᴰ (fct · arg) = fvᴰ fct ++ fvᴰ arg %fvᴰ (ƛ t) = rm₀ (fvᴰ t) %fvᴰ (Let t u) = fvᴰ t ++ rm₀ (fvᴰ u) % \vphantom{$\{$}\texttt{fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}List\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{4em}}{\char `\=}\mbox{\hspace{0.50em}}{[}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{]}{\nopagebreak \newline% }\vphantom{$\{$}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fct\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}arg\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}fct\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}arg{\nopagebreak \newline% }\vphantom{$\{$}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{4em}}{\char `\=}\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2em}}{\char `\=}\mbox{\hspace{0.50em}}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}++\mbox{\hspace{0.50em}}rm\makebox[0.61ex][l]{$ _{{0}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}fv\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Example{:} comparing terms for equality\label{napaCmpS}} % %paragraphName: intro As an example of a function that simultaneously traverses two terms, we show how to compare two terms for equality. We begin with a very simple homogeneous equality test, which has type \texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{\textbar{}Cmp\textbar{}\makebox[1.22ex][c]{{~}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}, that is, \texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Bool}. Then, we present a slightly more involved function, which compares two terms for equality up to a user-supplied notion of equality of their free names. This function is able to compare two terms in different worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} and{~}\texttt{\makebox[1.22ex][c]{$ \beta $}}, provided the user supplies a name comparator of type \texttt{\textbar{}Cmp\textbar{}\makebox[1.22ex][c]{{~}}Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}.% % %paragraphName: eqTmᴰ De Bruijn{'}s representation is canonical{:} two terms are $ \alpha $-equivalent if and only if their representations are identical. Thus, a homogeneous equality test is a plain and simple structural equality test. Polymorphic recursion is exploited{:} after crossing a binder, \texttt{eqTm\makebox[0.61ex][l]{\textsuperscript{D}}} is recursively invoked at{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1}.% {\nopagebreak } % %code: % %comment: eqTmᴰ : ∀ {α} → |Cmp| Tmᴰ α α %eqTmᴰ (V x) (V y) = x ==ᴺ y %eqTmᴰ (t · u) (v · w) = eqTmᴰ t v ∧ eqTmᴰ u w %eqTmᴰ (ƛ t) (ƛ u) = eqTmᴰ t u %eqTmᴰ (Let t u) (Let v w) = eqTmᴰ t v ∧ eqTmᴰ u w %eqTmᴰ _ _ = false % ~\\~\vphantom{$\{$}\texttt{eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}y{\nopagebreak \newline% }\vphantom{$\{$}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}v\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}w\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}w{\nopagebreak \newline% }\vphantom{$\{$}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}w\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}w{\nopagebreak \newline% }\vphantom{$\{$}eqTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{4.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{4.50em}}{\char `\=}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: cmpName↑ Let us now consider the slightly more difficult problem of comparing two terms up to a user-supplied comparator of their free names. Because all of the subtle work takes place at the level of names, we first define a separate and reusable function, called{~}\texttt{cmpName\makebox[1.22ex][c]{$ \uparrow $}}\index{Code!\texttt{cmpName\makebox[1.22ex][c]{$ \uparrow $}}}, which shifts a name comparator so that it can be used under{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} binders. It is analogous in spirit to{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}\index{Code!\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}} (section{~}\ref{convenienceS}), which shifts a name transformer. The name comparator \texttt{cmpName\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \Gamma $}} compares two names \texttt{x} and \texttt{y} in the following manner. If both are \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound, then they can be safely compared using{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}}} . If both are \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free, then they cannot be compared directly. They are compared by subtracting \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} and applying the original name comparator \texttt{\makebox[1.22ex][c]{$ \Gamma $}}. If one of them is \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound and the other is \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free, then they are considered different.% {\nopagebreak } % %code: % %comment: cmpName↑ : ∀ {α β} ℓ → |Cmp| Name α β % → |Cmp| Name (α ↑ ℓ) (β ↑ ℓ) %cmpName↑ ℓ Γ x y with x <ᴺ ℓ | y <ᴺ ℓ %... | inj₁ x′ | inj₁ y′ = x′ ==ᴺ y′ %... | inj₂ x′ | inj₂ y′ = Γ (x′ ∸ᴺ ℓ) (y′ ∸ᴺ ℓ) %... | _ | _ = false % ~\\~\vphantom{$\{$}\texttt{cmpName\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{10.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}cmpName\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}with\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}y\ensuremath{^{\prime}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}y\ensuremath{^{\prime}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}y\ensuremath{^{\prime}}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}y\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{3em}}\textbar{}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{3.50em}}{\char `\=}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: cmpTmᴰ It is now straightforward to define a function that compares two terms for equality, up to a user-supplied comparator of their free names. One compares the two terms in a simple structural fashion. One keeps track of the number{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} of binders that have been traversed, and one calls{~}\texttt{cmpName\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} at variables. Note that keeping incorrect track of{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} would lead to a type error.% {\nopagebreak } % %code: % %comment: cmpTmᴰ : ∀ {α β} → |Cmp| Name α β → |Cmp| Tmᴰ α β %cmpTmᴰ {α} {β} Γ = go 0 where % go : ∀ ℓ → |Cmp| Tmᴰ (α ↑ ℓ) (β ↑ ℓ) % go ℓ (V x) (V y) = cmpName↑ ℓ Γ x y % go ℓ (t · u) (v · w) = go ℓ t v ∧ go ℓ u w % go ℓ (ƛ t) (ƛ u) = go (suc ℓ) t u % go ℓ (Let t u) (Let v w) = go ℓ t v ∧ go (suc ℓ) u w % go _ _ _ = false % ~\\~\vphantom{$\{$}\texttt{cmpTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}cmpTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}go\mbox{\hspace{0.50em}}0\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}go\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}y\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}cmpName\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}y{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}v\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}w\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}w{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}w\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}v\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \wedge $}\mbox{\hspace{0.50em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u\mbox{\hspace{0.50em}}w{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}go\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{8.50em}}{\char `\=}\mbox{\hspace{0.50em}}false{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: _==Tmᴰ_ By instantiating the name comparator{~}\texttt{\makebox[1.22ex][c]{$ \Gamma $}} with the homogeneous name comparison function{~}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}}, we recover a homogeneous equality test, that is, an equality test for terms that inhabit a common world. This variant is however less efficient than \texttt{eqTm\makebox[0.61ex][l]{\textsuperscript{D}}}.% {\nopagebreak } % %code: % %comment: _==Tmᴰ_ : ∀ {α} → |Cmp| Tmᴰ α α %_==Tmᴰ_ = cmpTmᴰ _==ᴺ_ % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\textbar{}Cmp\textbar{}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}cmpTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}{\char `\=}{\char `\=}\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{\_{}}{\nopagebreak \newline% }\vphantom{$\{$}}% \subsection{Traversals\label{napaTraversal}} \subsubsection{A reusable traversal} % %paragraphName: TraverseTmᴰ As in the nominal setting (section \ref{kitsAndTraversals}), we build a generic term traversal function, so as to avoid code duplication among various operations on terms. Fortunately, in this nameless style, things are simpler. The information that must be carried down during the traversal can be summarized by a single natural number, namely the parameter{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} that we have already used. This parameter records how many binders have been entered.% {\nopagebreak } % %code: % %comment: module TraverseTmᴰ {E} (E-app : Applicative E) % {α β} (trName : ∀ ℓ → Name (α ↑ ℓ) % → E (Tmᴰ (β ↑ ℓ))) % where % open Applicative E-app % % tr : ∀ ℓ → Tmᴰ (α ↑ ℓ) → E (Tmᴰ (β ↑ ℓ)) % tr ℓ (V x) = trName ℓ x % tr ℓ (t · u) = pure _·_ ⊛ tr ℓ t ⊛ tr ℓ u % tr ℓ (ƛ t) = pure ƛ ⊛ tr (suc ℓ) t % tr ℓ (Let t u) = pure Let ⊛ tr ℓ t ⊛ tr (suc ℓ) u % % trTmᴰ : Tmᴰ α → E (Tmᴰ β) % trTmᴰ = tr 0 % ~\\~\vphantom{$\{$}\texttt{module\mbox{\hspace{0.50em}}TraverseTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{$ {(} $}E-app\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{8em}}\makebox[1.83ex][l]{ }\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}trName\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{8em}}\makebox[1.83ex][l]{ }\mbox{\hspace{10.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}open\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E-app{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}tr\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}trName\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{1.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}u\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}Let\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}tr\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}suc\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}tr\mbox{\hspace{0.50em}}0{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: trTmᴰ′ As in section{~}\ref{kitsAndTraversals}, we require that{~}\texttt{trName} map names to terms, and as a consequence, we do not wrap the call{~}\texttt{trName\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{{~}}x} with the data constructor{~}\texttt{V}. This allows us to obtain capture-avoiding substitution as an instance of \texttt{trTm\makebox[0.61ex][l]{\textsuperscript{D}}}. When one wishes to map names to names, one can use the following specialized version of \texttt{trTm\makebox[0.61ex][l]{\textsuperscript{D}}}, where the name-to-name transformation is composed with \texttt{V}.% {\nopagebreak } % %code: % %comment: open TraverseTmᴰ % %trTmᴰ′ : % ∀ {E} (E-app : Applicative E) {α β} % (trName : ∀ ℓ → Name (α ↑ ℓ) % → E (Name (β ↑ ℓ))) % → Tmᴰ α → E (Tmᴰ β) %trTmᴰ′ E-app trName % = trTmᴰ E-app (λ ℓ x → pure V ⊛ trName ℓ x) % where open Applicative E-app % ~\\~\vphantom{$\{$}\texttt{open\mbox{\hspace{0.50em}}TraverseTm\makebox[0.61ex][l]{\textsuperscript{D}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{:}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E-app\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}\makebox[1.22ex][l]{$ {(} $}trName\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{9em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}trName{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}pure\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\ensuremath{\npoasterisk}\mbox{\hspace{0.50em}}trName\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}x\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{2em}}where\mbox{\hspace{0.50em}}open\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E-app{\nopagebreak \newline% }\vphantom{$\{$}}% \subsubsection{Renaming terms} % %paragraphName: renameTmᴰA Composing the above function with (a generalized version of) \texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}\index{Code!\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}A}} yields a generic term renaming function, \texttt{renameTm\makebox[0.61ex][l]{\textsuperscript{D}}A}\index{Code!\texttt{renameTm\makebox[0.61ex][l]{\textsuperscript{D}}A}}. This function is parameterized with a user-supplied (and potentially effectful) renaming \texttt{$ \theta $} of the free variables.% {\nopagebreak } % %code: % %comment: -- Like protect↑, but generalized to applicative functors %protect↑A = {! omitted !} % %renameTmᴰA : ∀ {E} (E-app : Applicative E) % {α β} (θ : Name α → E (Name β)) % → (Tmᴰ α → E (Tmᴰ β)) %renameTmᴰA E-app θ % = trTmᴰ′ E-app (protect↑A E-app θ) % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}Like\mbox{\hspace{0.50em}}protect\makebox[1.22ex][c]{$ \uparrow $},\mbox{\hspace{0.50em}}but\mbox{\hspace{0.50em}}generalized\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}applicative\mbox{\hspace{0.50em}}functors{\nopagebreak \newline% }\vphantom{$\{$}protect\makebox[1.22ex][c]{$ \uparrow $}A\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}A\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}E\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}E-app\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Applicative\mbox{\hspace{0.50em}}E\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{7em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \theta $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}E\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}A\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}$ \theta ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}protect\makebox[1.22ex][c]{$ \uparrow $}A\mbox{\hspace{0.50em}}E-app\mbox{\hspace{0.50em}}$ \theta $\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: renameTmᴰ, renameTmᴰ? By instantiating \texttt{E} with the identity functor, we obtain a term renaming function that is parameterized with a total renaming of the free variables. By instantiating it with the functor{~}\texttt{Maybe}, we obtain a term renaming function that is parameterized with a partial renaming of the free variables.% {\nopagebreak } % %code: % %comment: renameTmᴰ : ∀ {α β} → (α →ᴺ β) → (Tmᴰ α → Tmᴰ β) %renameTmᴰ = renameTmᴰA id-app % %renameTmᴰ? : ∀ {α β} → (Name α →? Name β) % → (Tmᴰ α →? Tmᴰ β) %renameTmᴰ? = renameTmᴰA Maybe.applicative % ~\\~\vphantom{$\{$}\texttt{renameTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}A\mbox{\hspace{0.50em}}id-app{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{7.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}A\mbox{\hspace{0.50em}}Maybe.applicative{\nopagebreak \newline% }\vphantom{$\{$}}% \subsubsection{Shifting and coercing terms\label{liftingNameFunctionsS}} % %paragraphName: addTmᴰ Thanks to the above term renaming functions, any operation that maps names to names can be lifted to the level of terms. For instance, the operation of adding{~}\texttt{k} to a name can be lifted to the level of terms. This yields a function that adds{~}\texttt{k} to the free variables of a term{:}% {\nopagebreak } % %code: % %comment: addTmᴰ : ∀ {α} k → Tmᴰ α → Tmᴰ (α +ᵂ k) %addTmᴰ = renameTmᴰ ∘ addᴺ % ~\\~\vphantom{$\{$}\texttt{addTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}addTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}add\makebox[0.61ex][l]{\textsuperscript{N}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: shiftTmᴰ Although the above definition is concise and elegant, it is somewhat unsatisfactory. Indeed, because{~}\texttt{renameTm\makebox[0.61ex][l]{\textsuperscript{D}}} uses{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}, we effectively end up using a combination of{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}} and{~}\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}} which we have noted is slightly inefficient (see the discussion of{~}\texttt{shiftName\ensuremath{^{\prime}}} in section{~}\ref{convenienceS}). The function{~}\texttt{shiftName} offers a more efficient alternative. This leads us to the following definition of{~}\texttt{shiftTm\makebox[0.61ex][l]{\textsuperscript{D}}}, a function that adds{~}\texttt{k} to the free variables of a term{:}% {\nopagebreak } % %code: % %comment: shiftTmᴰ : ∀ {α β} k → (α +ᵂ k) ⊆ β → (Tmᴰ α → Tmᴰ β) %shiftTmᴰ k p = trTmᴰ′ id-app (λ ℓ → shiftName ℓ k p) % ~\\~\vphantom{$\{$}\texttt{shiftTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}shiftTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}p\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}id-app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \lambda $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}shiftName\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}p\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: subtractTmᴰ, subtractTmᴰ? The operations{~}\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}} and{~}\texttt{subtract\makebox[0.61ex][l]{\textsuperscript{N}}?} can also be lifted to the level of terms. We obtain functions that subtract (or attempt to subtract) a natural number{~}\texttt{k} from the free variables of a term{:}% {\nopagebreak } % %code: % %comment: subtractTmᴰ : ∀ {α} k → Tmᴰ (α +ᵂ k) → Tmᴰ α %subtractTmᴰ = renameTmᴰ ∘ subtractᴺ % ~\\~\vphantom{$\{$}\texttt{subtractTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}subtractTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}subtract\makebox[0.61ex][l]{\textsuperscript{N}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: subtractTmᴰ? : ∀ {α} ℓ → Tmᴰ (α ↑ ℓ) →? Tmᴰ α %subtractTmᴰ? = renameTmᴰ? ∘ subtractᴺ? % \vphantom{$\{$}\texttt{subtractTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}subtractTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}subtract\makebox[0.61ex][l]{\textsuperscript{N}}?{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: coerceTmᴰ The operation{~}\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}} can also be lifted to terms by using{~}\texttt{renameTm\makebox[0.61ex][l]{\textsuperscript{D}}}. However, it is preferable to use{~}\texttt{trTm\makebox[0.61ex][l]{\textsuperscript{D}}\ensuremath{^{\prime}}} in a direct manner, as follows{:}% {\nopagebreak } % %code: % %comment: coerceTmᴰ : ∀ {α β} → α ⊆ β → (Tmᴰ α → Tmᴰ β) %coerceTmᴰ pf = trTmᴰ′ id-app (coerceᴺ ∘ ⊆-cong-↑ pf) %-- or less efficiently: %-- coerceTmᴰ = renameTmᴰ ∘ coerceᴺ % ~\\~\vphantom{$\{$}\texttt{coerceTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}coerceTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}pf\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}id-app\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-cong-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}pf\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}or\mbox{\hspace{0.50em}}less\mbox{\hspace{0.50em}}efficiently{:}{\nopagebreak \newline% }\vphantom{$\{$}--\mbox{\hspace{0.50em}}coerceTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: coerceTmᴰ (continued) The existence of two possible definitions of{~}\texttt{coerceTm\makebox[0.61ex][l]{\textsuperscript{D}}} reflects the fact that there are two ways of turning a proof{~}\texttt{pf} of{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}} into a {``}shifted{''} name transformer of type \texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}}{ }\texttt{\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}}. One way is to first turn{~}\texttt{pf} into a name transformer of type \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}} and then apply{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}. This is written \texttt{protect\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}$ \circ $}{ }\texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}pf}. This works, but{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}} involves a dynamic test, because, in general, it treats \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound and \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free names differently. The other way is to first turn{~}\texttt{pf} into a proof of \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \subseteq $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} and then turn this proof into a name transformer. This is written \texttt{coerce\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}$ \circ $\makebox[1.22ex][c]{{~}}\makebox[1.83ex][c]{$ \subseteq $}-cong-\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}pf}. This term has no computational content{:} up to erasure, it is the identity.% % %paragraphName: closeTmᴰ? Finally, a function that tests whether a term is closed can be defined in the same manner as in the nominal setting (section{~}\ref{kitsAndTraversals}){:}% {\nopagebreak } % %code: % %comment: closeTmᴰ? : ∀ {α} → Tmᴰ α →? Tmᴰ ø %closeTmᴰ? = renameTmᴰ? (const nothing) -- a free var causes a failure % ~\\~\vphantom{$\{$}\texttt{closeTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $?\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \emptyset $}{\nopagebreak \newline% }\vphantom{$\{$}closeTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}?\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}const\mbox{\hspace{0.50em}}nothing\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}free\mbox{\hspace{0.50em}}var\mbox{\hspace{0.50em}}causes\mbox{\hspace{0.50em}}a\mbox{\hspace{0.50em}}failure{\nopagebreak \newline% }\vphantom{$\{$}}% \subsubsection{Capture-avoiding substitution} % %paragraphName: substVar To implement capture-avoiding substitution for the type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}}, all we need is a specific \texttt{trName} that we can pass to{~}\texttt{trTm\makebox[0.61ex][l]{\textsuperscript{D}}}. If a user-supplied substitution is represented as a function of names to terms, of type{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}, then all we need is to {``}shift{''} this function so that it can be used under{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} binders. This is done by the following function, which again is analogous in spirit to{~}\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}\index{Code!\texttt{protect\makebox[1.22ex][c]{$ \uparrow $}}}.% {\nopagebreak } % %code: % %comment: substVarTmᴰ : ∀ {α β} → (Name α → Tmᴰ β) → % ∀ ℓ → Name (α ↑ ℓ) → Tmᴰ (β ↑ ℓ) %substVarTmᴰ f ℓ x % with x <ᴺ ℓ %... | inj₁ x′ = V (x′ ⟨-because ⊆-cong-↑ ⊆-ø ℓ -⟩) %... | inj₂ x′ = shiftTmᴰ ℓ (⊆-+-↑ ℓ) (f (x′ ∸ᴺ ℓ)) % ~\\~\vphantom{$\{$}\texttt{substVarTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3.50em}}\makebox[1.83ex][l]{ }\mbox{\hspace{2.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}substVarTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{3em}}with\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\textless{}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}V\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\ensuremath{^{\prime}}\mbox{\hspace{1em}}\makebox[0.61ex][c]{\ensuremath{\langle}}-because\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-cong-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \subseteq $}-\makebox[1.22ex][c]{$ \emptyset $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}-\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}...\mbox{\hspace{0.50em}}\textbar{}\mbox{\hspace{0.50em}}inj\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}shiftTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-+-\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: substTmᴰ Capture-avoiding substitution is then obtained by instantiating \texttt{trTm\makebox[0.61ex][l]{\textsuperscript{D}}} with the identity applicative functor and composing it with \texttt{substVarTm\makebox[0.61ex][l]{\textsuperscript{D}}}{:}% {\nopagebreak } % %code: % %comment: substTmᴰ : ∀ {α β} → (Name α → Tmᴰ β) → (Tmᴰ α → Tmᴰ β) %substTmᴰ = trTmᴰ id-app ∘ substVarTmᴰ % ~\\~\vphantom{$\{$}\texttt{substTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}substTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}trTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}id-app\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}substVarTm\makebox[0.61ex][l]{\textsuperscript{D}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: β-redᴰ As an illustration, here is again a simple function that performs a $ \beta $-reduction when a $ \beta $-redex appears at the root of its argument{:}% {\nopagebreak } % %code: % %comment: β-redᴰ : ∀ {α} → Tmᴰ α → Tmᴰ α %β-redᴰ (ƛ fct · arg) = substTmᴰ (subtractWithᴺ 1 arg V) fct %β-redᴰ t = t % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{$ \beta $}-red\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \beta $}-red\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}fct\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}arg\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}substTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}subtractWith\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}1\mbox{\hspace{0.50em}}arg\mbox{\hspace{0.50em}}V\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}fct{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \beta $}-red\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}t\mbox{\hspace{6.50em}}{\char `\=}\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}}% \section{Soundness of \textsc{NomPa} (de Bruijn fragment)\label{napaRel}} % %paragraphName: summary We now extend our soundness proof so as to cover the new types and operations of figure{~}\ref{napaIfaceF}. The required definitions and proofs (section{~}\ref{deBruijnProofS}) are fairly immediate. What is perhaps less obvious is exactly what guarantees are offered by the resulting {``}free theorems{''}. We informally show that more precise types lead to stronger {``}free theorems{''} (section{~}\ref{strengthThm}). Furthermore, as a case study, we formally study the {``}free theorem{''} associated with world-polymorphic term transformation functions, and we prove that every such function commutes with a renaming of the free variables of its argument (section{~}\ref{usingParam}).% \subsection{Extending the logical relation and proofs\label{deBruijnProofS}} % %paragraphName: world operation lemmas Because we have introduced a new abstract operation{~}\texttt{\makebox[1.22ex][c]{\_{}}+1}, which maps a world to a world, we must now define the corresponding operation{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}}, which maps a relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} between two worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}} and \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}} to a relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} between the worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}+1} and \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}+1}. Only one definition makes sense{:} the relation \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} must be the image of the relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} under the translation {``}up by one{''}. This is depicted in figure{~}\ref{shiftingVsAddingF}. The definition (in pseudo-code) is as follows{:}% {\nopagebreak } % %code: % %comment: _⟦+1⟧ : (⟦World⟧ ⟦→⟧ ⟦World⟧) _+1 _+1 %αᵣ ⟦+1⟧ ≝ { (x+1, y+1) | (x, y) ∈ αᵣ } -- not proper Agda % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}+1\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}+1{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\ensuremath{\stackrel{\mathtt{{\scriptscriptstyle def}}}{=}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}x+1,\makebox[1.22ex][c]{{~}}y+1\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}\textbar{}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}x,\makebox[1.22ex][c]{{~}}y\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \in $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}not\mbox{\hspace{0.50em}}proper\mbox{\hspace{0.50em}}Agda{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: world operation lemmas (continued) The definition of the operation \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1} in terms of \texttt{\makebox[1.22ex][c]{\_{}}+1} gives rise to an analogous definition of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}} in terms of{~}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}\index{Code!\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}}. The effect of this operation on a relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is to translate it up by one and then to add the pair (0,{ }0). This is also depicted in figure{~}\ref{shiftingVsAddingF}.% {\nopagebreak } % %code: % %comment: _⟦↑1⟧ : (⟦World⟧ ⟦→⟧ ⟦World⟧) _↑1 _↑1 %_⟦↑1⟧ αᵣ = ⟦zeroᴮ⟧ ⟦◅⟧ (αᵣ ⟦+1⟧) % ~\\~\vphantom{$\{$}\texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}1{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}zero\makebox[0.61ex][l]{\textsuperscript{B}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: figure \begin{figure}[] \begin{flushleft} \begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path[-] (0L) edge node [above]{}(3R); \path[-] (3L) edge node [above]{}(0R); \path[-] (2L) edge node [above]{}(2R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path node (4L)[above of=3L]{$ \bullet $}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{4}; \path node (4R)[right of=4L,right=1cm of 4L]{$ \bullet $}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{4}; \path[-] (1L) edge node [above]{}(4R); \path[-] (4L) edge node [above]{}(1R); \path[-] (3L) edge node [above]{}(3R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}+1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path node (4L)[above of=3L]{$ \bullet $}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{4}; \path node (4R)[right of=4L,right=1cm of 4L]{$ \bullet $}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{4}; \path[-] (1L) edge node [above]{}(4R); \path[-] (4L) edge node [above]{}(1R); \path[-] (3L) edge node [above]{}(3R); \path[-] (0L) edge node [above]{}(0R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} \end{center} \end{minipage} \end{flushleft} \caption{Translating and shifting relations\label{shiftingVsAddingF}} \end{figure}% % %paragraphName: addᴺ, subtractᴺ There remains to check that the operations and the world inclusion rules of figure{~}\ref{napaIfaceF} are well-behaved, that is, they fit the logical relation. In almost all cases, the proof is immediate. In the case of{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}}, it turns out that our implementation of{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}} is not very well suited to a direct proof. We provide an alternative implementation, which we prove is extensionally equivalent to{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}} and is well-behaved. Because the logical relation is compatible with extensional equality, this allows us to conclude that{~}\texttt{cmp\makebox[0.61ex][l]{\textsuperscript{N}}} itself is well-behaved.% \subsection{A free theorem{:} world-polymorphic functions commute with renamings\label{usingParam}} % %paragraphName: alpha-purity becomes trivial In the nominal setting, we exploited the logical relation and parametricity in order to prove that two $ \alpha $-equivalent terms could not be distinguished, or in other words, that two representations of a single object-level term could not be distinguished. This was a non-trivial property because a single object-level term could have multiple representations. In the de Bruijn setting, the situation is somewhat different. De Bruijn{'}s representation is canonical{:} an object-level term has exactly one representation. Thus, the fact that {``}$ \alpha $-equivalent terms cannot be distinguished{''} becomes a tautology.% % %paragraphName: there still remain interesting things to prove Nevertheless, in this setting, parametricity can still be exploited in order to establish non-trivial properties of well-typed programs. One such property is the fact that {``}world-polymorphic homogeneous term transformers commute with renamings{''}, that is, every function{~}\texttt{f} of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} commutes with a renaming of the free variables. In other words, every such function is equivariant{~}\cite{pitts-06}. Intuitively, this means that the function{~}\texttt{f} must treat the free variables of its argument as {``}black boxes{''}. It can test whether two free variables are equal, but it cannot depend on the manner in which the free variables happen to be {``}named{''} (numbered).% % %paragraphName: Ren In the following, we choose a {``}renaming{''} to be an injective function{~}\texttt{$ \Phi $} of names to names. The type of a renaming that maps names in the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} to names in the world{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} is{~}\texttt{Ren\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}. Note that there is a slight difference between a renaming from{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} to{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} (\texttt{Ren\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}) and the worlds{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} and{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} being {``}related{''} (\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \beta $}}. On renamings, we define three functions{~}\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{N}}}\index{Code!\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{N}}}}, \texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}}\index{Code!\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}}} and{~}\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}}\index{Code!\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}}} which respectively turn a renaming into a function of names to names, into a relation between worlds, and into a function of terms to terms.% {\nopagebreak } % %code: % %comment: Ren : (α₁ α₂ : World) → Set %Ren α₁ α₂ = Injection (Nm α₁) (Nm α₂) % -- * Injection From To is the set of the injective functions % -- from the setoid From to the setoid To. % -- * Nm α is the setoid on Name α % %⟨_⟩ᴺ : ∀ {α β} → Ren α β → (α →ᴺ β) %⟨ Φ ⟩ᴺ = {! omitted !} -- Projects out the function over names % %⟨_⟩ᵂ : ∀ {α β} → Ren α β → ⟦World⟧ α β %⟨_⟩ᵂ {α} {β} Φ = ℛ , ℛ-pres-≡ % where ℛ : Name α → Name β → Set % ℛ x y = ⟨ Φ ⟩ᴺ x ≡ y % ℛ-pres-≡ : Preserve-≡ ℛ % ℛ-pres-≡ = {! omitted !} % %⟨_⟩™ : ∀ {α β} → Ren α β → (Tmᴰ α → Tmᴰ β) %⟨ Φ ⟩™ = renameTmᴰ ⟨ Φ ⟩ᴺ % ~\\~\vphantom{$\{$}\texttt{Ren\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}Ren\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}Injection\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Nm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Nm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}--\mbox{\hspace{0.50em}}*\mbox{\hspace{0.50em}}Injection\mbox{\hspace{0.50em}}From\mbox{\hspace{0.50em}}To\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}set\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}injective\mbox{\hspace{0.50em}}functions{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}--\mbox{\hspace{1.50em}}from\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}setoid\mbox{\hspace{0.50em}}From\mbox{\hspace{0.50em}}to\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}setoid\mbox{\hspace{0.50em}}To.{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}--\mbox{\hspace{0.50em}}*\mbox{\hspace{0.50em}}Nm\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}setoid\mbox{\hspace{0.50em}}on\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Ren\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}--\mbox{\hspace{0.50em}}Projects\mbox{\hspace{0.50em}}out\mbox{\hspace{0.50em}}the\mbox{\hspace{0.50em}}function\mbox{\hspace{0.50em}}over\mbox{\hspace{0.50em}}names{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Ren\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}},\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}-pres-$ \equiv ${\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}where\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Name\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}y\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}y{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}-pres-$ \equiv $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Preserve-$ \equiv $\mbox{\hspace{0.50em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{4em}}\makebox[1.83ex][c]{$ \mathcal{{R}} $}-pres-$ \equiv $\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{\_{}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Ren\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}renameTm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{N}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⟦Tmᴰ⟧ In order to establish that {``}world-polymorphic homogeneous term transformers commute with renamings{''}, the key is to examine how the logical relation behaves at the type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}}. As described in section{~}\ref{rellogRecapS}, the definition of the relation{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}} is mechanically generated from the definition of the type{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}}{:}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}}% {\nopagebreak } % %code: % %comment: data ⟦Tmᴰ⟧ {α₁ α₂} (αᵣ : ⟦World⟧ α₁ α₂) : Tmᴰ α₁ → Tmᴰ α₂ → Set where % ⟦V⟧ : ∀ {x₁ x₂} (xᵣ : ⟦Name⟧ αᵣ x₁ x₂) % → ⟦Tmᴰ⟧ αᵣ (V x₁) (V x₂) % _⟦·⟧_ : ∀ {t₁ t₂ u₁ u₂} % (tᵣ : ⟦Tmᴰ⟧ αᵣ t₁ t₂) % (uᵣ : ⟦Tmᴰ⟧ αᵣ u₁ u₂) % → ⟦Tmᴰ⟧ αᵣ (t₁ · u₁) (t₂ · u₂) % ⟦ƛ⟧ : ∀ {t₁ t₂} (tᵣ : ⟦Tmᴰ⟧ (αᵣ ⟦↑1⟧) t₁ t₂) % → ⟦Tmᴰ⟧ αᵣ (ƛ t₁) (ƛ t₂) % ⟦Let⟧ : ∀ {t₁ t₂ u₁ u₂} % (tᵣ : ⟦Tmᴰ⟧ αᵣ t₁ t₂) % (uᵣ : ⟦Tmᴰ⟧ (αᵣ ⟦↑1⟧) u₁ u₂) % → ⟦Tmᴰ⟧ αᵣ (Let t₁ u₁) (Let t₂ u₂) % ~\\~\vphantom{$\{$}\texttt{data\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set\mbox{\hspace{0.50em}}where{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}V\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}x\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Name\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}V\mbox{\hspace{0.50em}}x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \cdotp $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{$ {(} $}t\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{$ {(} $}u\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \cdotp $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{{\nptextcrlambda}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{2em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}t\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{{\nptextcrlambda}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Let\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{$ {(} $}t\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{$ {(} $}u\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Let\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}u\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ⟦Tmᴰ⟧ (continued) Let us informally study the meaning of this definition. The parameter{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is {``}shifted{''} when a binding construct is entered, and is used at variables. Thus, when two terms are related by{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, two matching variable occurrences{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}} that lie under{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} binders must be related by{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}. This means that either{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}} are both \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound and{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} is equal to{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}}, or{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}} are both \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free and \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} relates{~}\texttt{x\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}-\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} and{~}\texttt{x\makebox[0.61ex][l]{$ _{{2}} $}\makebox[1.22ex][c]{{~}}-\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}. One may summarize this by stating that two terms are related by{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} if and only if they are identical, except for their free variables, which are related by{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}.% % %paragraphName: ⟦Tmᴰ⟧⇔rename We formally prove that for any renaming{~}\texttt{$ \Phi $} of type{~}\texttt{Ren\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{1}} $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{$ _{{2}} $}}, two terms{~}\texttt{t\makebox[0.61ex][l]{$ _{{1}} $}} and{~}\texttt{t\makebox[0.61ex][l]{$ _{{2}} $}} are related by{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{{~}}$ \Phi $\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}} if and only if{~}\texttt{t\makebox[0.61ex][l]{$ _{{2}} $}} is the image of{~}\texttt{t\makebox[0.61ex][l]{$ _{{1}} $}} under the renaming{~}\texttt{$ \Phi $}{:}% {\nopagebreak } % %code: % %comment: Rename : ∀ {α β} → Ren α β → Tmᴰ α → Tmᴰ β → Set %Rename Φ t₁ t₂ = ⟨ Φ ⟩™ t₁ ≡ t₂ % %⟦Tmᴰ⟧⇔Rename : ∀ {α β} (Φ : Ren α β) → ⟦Tmᴰ⟧ ⟨ Φ ⟩ᵂ ⇔ Rename Φ % ~\\~\vphantom{$\{$}\texttt{Rename\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Ren\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Set{\nopagebreak \newline% }\vphantom{$\{$}Rename\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{1}} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}t\makebox[0.61ex][l]{$ _{{2}} $}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}$ \Leftrightarrow $Rename\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \Phi $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ren\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}$ \Leftrightarrow $\mbox{\hspace{0.50em}}Rename\mbox{\hspace{0.50em}}$ \Phi ${\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: ren-comm Now, let{~}\texttt{f} be a world-polymorphic term transformer, and let{~}\texttt{f\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} be a proof that{~}\texttt{f} is well-behaved. (That is, \texttt{f\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is the {``}free theorem{''}, instantiated with{~}\texttt{f}.) Then, it is easy to prove that every renaming{~}\texttt{$ \Phi $} commutes with{~}\texttt{f}. Indeed, by instantiating{~}\texttt{f\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} with the relation{~}\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{{~}}$ \Phi $\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}}, we find that{~}\texttt{f} must map \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{{~}}$ \Phi $\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}}-related arguments to \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{{~}}$ \Phi $\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}}-related results. Then, by applying the lemma{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}$ \Leftrightarrow $Rename}\index{Code!\texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}$ \Leftrightarrow $Rename}} in both directions, we find that renaming a term before applying{~}\texttt{f} to it has the same effect as applying{~}\texttt{f} first and renaming the result. In other words, the functions{~}\texttt{\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{{~}}$ \Phi $\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\makebox[1.22ex][c]{{~}}$ \circ $\makebox[1.22ex][c]{{~}}f} and{~}\texttt{f\makebox[1.22ex][c]{{~}}$ \circ $\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\langle}}\makebox[1.22ex][c]{{~}}$ \Phi $\makebox[1.22ex][c]{{~}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}} are extensionally equivalent.% {\nopagebreak } % %code: % %comment: -- Pointwise equality %f ≗ g = ∀ x → f x ≡ g x % ~\\~\vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}Pointwise\mbox{\hspace{0.50em}}equality{\nopagebreak \newline% }\vphantom{$\{$}f\mbox{\hspace{0.50em}}\ensuremath{\circeq}\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}x\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}g\mbox{\hspace{0.50em}}x{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: ren-comm : (f : ∀ {α} → Tmᴰ α → Tmᴰ α) % (fᵣ : (∀⟨ αᵣ ∶ ⟦World⟧ ⟩⟦→⟧ ⟦Tmᴰ⟧ αᵣ ⟦→⟧ ⟦Tmᴰ⟧ αᵣ) f f) % {α β : World} (Φ : Ren α β) % → ⟨ Φ ⟩™ ∘ f ≗ f ∘ ⟨ Φ ⟩™ %ren-comm f fᵣ Φ t % = ⟦Tmᴰ⟧⇒Rename Φ (fᵣ ⟨ Φ ⟩ᵂ (Rename⇒⟦Tmᴰ⟧ Φ ≡.refl)) % \vphantom{$\{$}\texttt{ren-comm\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{1em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \forall $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\ensuremath{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}World\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \rightarrow $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}f\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{5.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}World\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}$ \Phi $\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}Ren\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \beta $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{6em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\ensuremath{\circeq}\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}{\nopagebreak \newline% }\vphantom{$\{$}ren-comm\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}t{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}$ \Rightarrow $Rename\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Rename$ \Rightarrow $\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}$ \equiv $.refl\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %code: {\noindent}% %comment: -- The proof, step by step: % %⟨ Φ ⟩™ t ≡ ⟨ Φ ⟩™ t {- definition of Rename -} %Rename Φ t (⟨ Φ ⟩™ t) {- Rename Φ ⇒ ⟦Tmᴰ⟧ ⟨ Φ ⟩ᵂ -} %⟦Tmᴰ⟧ ⟨ Φ ⟩ᵂ t (⟨ Φ ⟩™ t) {- parametricity of f (called fᵣ) -} %⟦Tmᴰ⟧ ⟨ Φ ⟩ᵂ (f t) (f (⟨ Φ ⟩™ t)) {- ⟦Tmᴰ⟧ ⟨ Φ ⟩ᵂ ⇒ Rename Φ -} %Rename Φ (f t) (f (⟨ Φ ⟩™ t)) {- definition of Rename -} %⟨ Φ ⟩™ (f t) ≡ ⟨ Φ ⟩™ (f t) {- definition of _≗_ -} %⟨ Φ ⟩™ ∘ f ≗ ⟨ Φ ⟩™ ∘ f % \vphantom{$\{$}\texttt{--\mbox{\hspace{0.50em}}The\mbox{\hspace{0.50em}}proof,\mbox{\hspace{0.50em}}step\mbox{\hspace{0.50em}}by\mbox{\hspace{0.50em}}step{:}{\nopagebreak \newline% }\vphantom{$\{$}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}t\mbox{\hspace{7.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}definition\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}Rename\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}Rename\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{6.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}Rename\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}$ \Rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{5.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}parametricity\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}called\mbox{\hspace{0.50em}}f\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{1.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}$ \Rightarrow $\mbox{\hspace{0.50em}}Rename\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}Rename\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{2.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}definition\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}Rename\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}f\mbox{\hspace{0.50em}}t\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{3.50em}}\makebox[1.22ex][l]{\{{}}-\mbox{\hspace{0.50em}}definition\mbox{\hspace{0.50em}}of\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\_{}}\ensuremath{\circeq}\makebox[1.22ex][c]{\_{}}\mbox{\hspace{0.50em}}-\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}f\mbox{\hspace{0.50em}}\ensuremath{\circeq}\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\langle}}\mbox{\hspace{0.50em}}$ \Phi $\mbox{\hspace{0.50em}}\makebox[0.61ex][c]{\ensuremath{\rangle}}\textsuperscript{T}\textsuperscript{m}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}f{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Category Theory: pointers A reviewer pointed out that the idea that "any world-polymorphic function commutes with renamings" comes up in the category-theoretic accounts of variable binding, such as Stark{'}s Ph.D thesis{~}\cite{stark-94} and also in Fiore, Plotkin, and Turi{'}s{~}\cite{fiore-plotkin-turi-99}.% % %paragraphName: Category Theory: presheaf The type of terms forms a presheaf over a category whose objects are worlds and morphisms are renamings. The condition{~}\texttt{ren-comm} states exactly that world-polymorphic functions between terms can be seen as morphisms in the same presheaf category. We do acknowledge the existence of this connection, but cannot give here a detailed account of it{:} more space and more work would be required.% \subsection{On the strength of free theorems\label{strengthThm}} % %paragraphName: free theorems Every type comes with a {``}free theorem{''} (section{~}\ref{rellogRecapS}). We have just exploited the free theorem associated with the type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} to establish that every function of this type commutes with renamings. In general, the meaning and strength of the free theorem varies greatly with the type that is considered. For instance, at type{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}}, the free theorem says{:} {``}every term of type{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}} is equal to itself{''}, a tautology. At type{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Bool}, the free theorem says{:} {``}every function of type{~}\texttt{\makebox[1.83ex][c]{$ \mathbb{{N}} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Bool} is deterministic{''}, that is, every such function maps equal arguments to equal results. This is again a tautology, since \textsc{Agda} is a pure language. At type{~}\texttt{\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][l]{\{{}}A\makebox[1.22ex][c]{{~}}{:}\makebox[1.22ex][c]{{~}}Set\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{A\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}A}, the free theorem can be used to prove that {``}every function of this type behaves as the identity function{''}, a much stronger statement. The universal quantification over{~}\texttt{A} is key to the strength of this theorem.% \subsubsection{Free theorems for homogeneous term transformers} % %paragraphName: intro We now discuss what can affect the strength of the free theorems in our context. For simplicity, we continue to focus on homogeneous term transformers, that is, on functions that map a term to a term in the same world.% % %paragraphName: various world types Naturally, polymorphism again plays an important role in the strength of free theorems. In this case, however, there is no type polymorphism, since these functions map terms to terms. What matters instead is world polymorphism. There are several ways in which a homogeneous term transformer can be world-polymorphic. Obviously, it can be parameterized with a world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} and work with terms of type \texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. It can also be parameterized with a natural number{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} and work with terms of type \texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}}. Or, somewhere in between these two approaches, it can be parameterized with both{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} and{~}\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}} and work with terms of type \texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}}. The relations that correspond to these various forms of worlds have different shapes, suggested in figure{~}\ref{variousTermTypesF}. The more constrained the shape of the relation, the weaker the free theorem, because the free theorem is universally quantified over all relations of that shape.% % %paragraphName: figure \begin{figure}[] \begin{flushleft} \begin{center} \begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path[-] (0L) edge node [above]{}(0R); \path[-] (1L) edge node [above]{}(1R); \path[-] (2L) edge node [above]{}(2R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}3\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path[-] (0L) edge node [above]{}(3R); \path[-] (3L) edge node [above]{}(0R); \path[-] (2L) edge node [above]{}(2R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){$ \bullet $}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{0}; \path node (0R)[right of=0L,right=1cm of 0L]{$ \bullet $}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{0}; \path node (1L)[above of=0L]{$ \bullet $}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{1}; \path node (1R)[right of=1L,right=1cm of 1L]{$ \bullet $}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{1}; \path node (2L)[above of=1L]{$ \bullet $}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{2}; \path node (2R)[right of=2L,right=1cm of 2L]{$ \bullet $}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{2}; \path node (3L)[above of=2L]{$ \bullet $}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{3}; \path node (3R)[right of=3L,right=1cm of 3L]{$ \bullet $}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{3}; \path node (4L)[above of=3L]{$ \bullet $}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{4}; \path node (4R)[right of=4L,right=1cm of 4L]{$ \bullet $}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{4}; \path node (5L)[above of=4L]{$ \bullet $}; \path node (5LT)[left of=5L,left=-0.5cm of 5L]{5}; \path node (5R)[right of=5L,right=1cm of 5L]{$ \bullet $}; \path node (5RT)[right of=5R,right=-0.5cm of 5R]{5}; \path node (6L)[above of=5L]{$ \bullet $}; \path node (6LT)[left of=6L,left=-0.5cm of 6L]{6}; \path node (6R)[right of=6L,right=1cm of 6L]{$ \bullet $}; \path node (6RT)[right of=6R,right=-0.5cm of 6R]{6}; \path[-] (3L) edge node [above]{}(6R); \path[-] (6L) edge node [above]{}(3R); \path[-] (5L) edge node [above]{}(5R); \path[-] (0L) edge node [above]{}(0R); \path[-] (1L) edge node [above]{}(1R); \path[-] (2L) edge node [above]{}(2R); \end{scope} \end{tikzpicture} \end{center}% \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}3\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} \end{center} \end{minipage} \end{center} \end{flushleft} \caption{Various typical forms of worlds and their relations\label{variousTermTypesF}} \end{figure}% % %paragraphName: the weakest Among these three forms of worlds, the most constrained one is \texttt{\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}. This world corresponds to the interval{~}{[}0,{~}\ensuremath{\ell}), or in other words, to the type \texttt{Fin\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}}. Thus, type-checking alone guarantees that a term transformer of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}} maps terms whose indices are in the range{~}{[}0,{~}\ensuremath{\ell}) to terms whose indices are also in this range. This is the same guarantee that is offered by the \texttt{Fin} approach. It turns out that the free theorem associated with this type does not offer anything beyond this guarantee. Indeed, as suggested by figure{~}\ref{variousTermTypesF}, the relation \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} is the identity relation on the interval{~}{[}0,{~}\ensuremath{\ell}). As a result, the free theorem states that {``}a term transformer of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}} maps equal arguments to equal results{''}, which is trivial. In summary and as noted earlier (section{~}\ref{newOpNameS}), every program that is well-typed in the \texttt{Fin} approach can be translated in our system by replacing \texttt{Fin\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} with \texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}}, but no new guarantees are magically obtained by doing so.% % %paragraphName: Tmᴰ α At the opposite end, among these three forms of worlds, the least constrained one is \texttt{\makebox[1.22ex][c]{$ \alpha $}}. That is, the strongest possible free theorem is obtained by quantifying over an arbitrary world. As proved earlier (section{~}\ref{usingParam}), this theorem implies that {``}a term transformer of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} commutes with an arbitrary renaming{''}. Thus, there are strictly fewer functions of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} than there are functions of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}}. Pragmatically, this means that, by declaring the former type instead of the latter, one makes it possible for the type-checker to detect more programming errors. This includes the family of errors where one {``}forgets to shift{''} a free variable and inadvertently turns it into a bound variable. In contrast, the \texttt{Fin} approach does not guarantee that these errors are detected.% % %paragraphName: Tmᴰ (α ↑ ℓ) In terms of abstraction, the world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} is in between{~}\texttt{\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. As suggested by figure{~}\ref{variousTermTypesF}, a relation of the form \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\llbracket}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} must be the identity on the interval{~}{[}0,{~}\ensuremath{\ell}), but can exhibit arbitrary structure above this interval. When working in de Bruijn style, a term transformer that operates in a world of the form{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\ell}}} is often used as an auxiliary function in order to eventually obtain a term transformer that operates in a world of the form{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}. We have seen examples of this in sections{~}\ref{napaCmpS} and{~}\ref{napaTraversal}. For instance, here is a typical type for an auxiliary function that has access to some kind of information about \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound variables but must treat \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free variables in a parametric manner{:}% {\nopagebreak } % %code: % %comment: some-op : ∀ {α ℓ} → (Fin ℓ → Info) → Tmᴰ (α ↑ ℓ) → Tmᴰ (α ↑ ℓ) %some-op Γ t = {! omitted !} % ~\\~\vphantom{$\{$}\texttt{some-op\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}Fin\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Info\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}some-op\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \Gamma $}\mbox{\hspace{0.50em}}t\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}!\mbox{\hspace{0.50em}}omitted\mbox{\hspace{0.50em}}!\makebox[1.22ex][r]{\}{}}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: Tmᴰ (α ↑ ℓ) (continued) The free theorem associated with the type of{~}\texttt{some-op} guarantees that this function commutes with a renaming of the \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free variables.% % %paragraphName: extra arguments When reasoning about free theorems, one must keep in mind a potential pitfall{:} adding extra arguments to a function type can drastically decrease the strength of the associated free theorem. An extreme example of this phenomenon is the type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \equiv $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}}. The free theorem is {``}ruined{''} by the argument{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \equiv $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}}. Even though the theorem is universally quantified over a relation{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}}, the presence of this argument requires that{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} be the empty relation, and the free theorem becomes trivial. In this case, the problem is obvious{:} it is clear that the type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \equiv $\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} is isomorphic to{~}\texttt{Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[0.61ex][l]{\textsuperscript{D}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}}, whose free theorem is trivial. Sometimes, however, it is not immediately obvious how the presence of certain arguments affects the strength of the free theorem.% % %paragraphName: extra arguments: supply An interesting example where the presence of an extra argument does \emph{not} weaken the free theorem is offered by the type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}}{ }\texttt{\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}}{ }\texttt{$ \rightarrow $}{ }\texttt{Supply}{ }\texttt{\makebox[1.22ex][c]{$ \alpha $}}{ }\texttt{$ \rightarrow $}{ }\texttt{Term}{ }\texttt{\makebox[1.22ex][c]{$ \alpha $}}{ }\texttt{$ \rightarrow $}{ }\texttt{Term}{ }\texttt{\makebox[1.22ex][c]{$ \alpha $}}. This is the type of a homogeneous term transformer that is equipped with a supply of fresh names. It is the type of the normalization-by-evaluation algorithm (section{~}\ref{nbeS}). By definition of the type{~}\texttt{Supply} (section{~}\ref{renameKitS}), a supply is just a pair of a binder and a {``}fresh-for{''} assertion. By definition (figure{~}\ref{nompaRelTypesF}), the relations that govern binders and {``}fresh-for{''} assertions are full. Thus, the relation \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}Supply\makebox[1.22ex][c]{\ensuremath{\rrbracket}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} is full too{:} requiring that it be inhabited by two arbitrary supplies does not constrain{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[0.61ex][l]{\ensuremath{_{{r}}}}} in any way. As a result, the presence of this extra argument does not weaken the theorem. The free theorem associated with the type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Supply\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Term\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Term\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} still guarantees that every function of this type commutes with a renaming of the free variables. In fact, it also guarantees that {``}choices of fresh names do not matter{''}, that is, the result produced by such a function is independent of which supply is used.% \subsection{The influence of translating versus shifting\label{bugS}} % %paragraphName: figure \begin{figure}[] \begin{flushleft} \begin{center} \begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{\texttt{0}}; \path node (0R)[right of=0L,right=1cm of 0L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{\texttt{0}}; \path node (1L)[above of=0L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{\texttt{1}}; \path node (1R)[right of=1L,right=1cm of 1L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{\texttt{1}}; \path node (2L)[above of=1L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{\texttt{2}}; \path node (2R)[right of=2L,right=1cm of 2L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{\texttt{2}}; \path node (3L)[above of=2L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{\texttt{$ \vdots $}}; \path node (3R)[right of=3L,right=1cm of 3L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{\texttt{$ \vdots $}}; \path node (4L)[above of=3L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}1}}; \path node (4R)[right of=4L,right=1cm of 4L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}1}}; \path node (5L)[above of=4L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (5LT)[left of=5L,left=-0.5cm of 5L]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (5R)[right of=5L,right=1cm of 5L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (5RT)[right of=5R,right=-0.5cm of 5R]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (6L)[above of=5L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (6LT)[left of=6L,left=-0.5cm of 6L]{\texttt{1+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (6R)[right of=6L,right=1cm of 6L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (6RT)[right of=6R,right=-0.5cm of 6R]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (7L)[above of=6L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (7LT)[left of=7L,left=-0.5cm of 7L]{\texttt{2+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (7R)[right of=7L,right=1cm of 7L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (7RT)[right of=7R,right=-0.5cm of 7R]{\texttt{k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (8L)[above of=7L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (8LT)[left of=8L,left=-0.5cm of 8L]{\texttt{$ \vdots $}}; \path node (8R)[right of=8L,right=1cm of 8L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (8RT)[right of=8R,right=-0.5cm of 8R]{\texttt{1+k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (9L)[above of=8L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (9LT)[left of=9L,left=-0.5cm of 9L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (9R)[right of=9L,right=1cm of 9L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (9RT)[right of=9R,right=-0.5cm of 9R]{\texttt{2+k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (10L)[above of=9L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (10LT)[left of=10L,left=-0.5cm of 10L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (10R)[right of=10L,right=1cm of 10L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (10RT)[right of=10R,right=-0.5cm of 10R]{\texttt{$ \vdots $}}; \path[-] (8L) edge node [above]{}(10R); \path[-] (7L) edge node [above]{}(9R); \path[-] (6L) edge node [above]{}(8R); \path[-] (5L) edge node [above]{}(7R); \path[-] (4L) edge node [above]{}(4R); \path[-] (3L) edge node [above]{}(3R); \path[-] (2L) edge node [above]{}(2R); \path[-] (1L) edge node [above]{}(1R); \path[-] (0L) edge node [above]{}(0R); \end{scope} \end{tikzpicture} \end{center}% \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{\texttt{0}}; \path node (0R)[right of=0L,right=1cm of 0L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{\texttt{0}}; \path node (1L)[above of=0L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{\texttt{1}}; \path node (1R)[right of=1L,right=1cm of 1L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{\texttt{1}}; \path node (2L)[above of=1L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{\texttt{2}}; \path node (2R)[right of=2L,right=1cm of 2L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{\texttt{2}}; \path node (3L)[above of=2L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{\texttt{$ \vdots $}}; \path node (3R)[right of=3L,right=1cm of 3L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{\texttt{$ \vdots $}}; \path node (4L)[above of=3L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}1}}; \path node (4R)[right of=4L,right=1cm of 4L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}1}}; \path node (5L)[above of=4L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (5LT)[left of=5L,left=-0.5cm of 5L]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (5R)[right of=5L,right=1cm of 5L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (5RT)[right of=5R,right=-0.5cm of 5R]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (6L)[above of=5L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (6LT)[left of=6L,left=-0.5cm of 6L]{\texttt{1+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (6R)[right of=6L,right=1cm of 6L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (6RT)[right of=6R,right=-0.5cm of 6R]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (7L)[above of=6L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (7LT)[left of=7L,left=-0.5cm of 7L]{\texttt{2+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (7R)[right of=7L,right=1cm of 7L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (7RT)[right of=7R,right=-0.5cm of 7R]{\texttt{k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (8L)[above of=7L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (8LT)[left of=8L,left=-0.5cm of 8L]{\texttt{$ \vdots $}}; \path node (8R)[right of=8L,right=1cm of 8L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (8RT)[right of=8R,right=-0.5cm of 8R]{\texttt{1+k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (9L)[above of=8L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (9LT)[left of=9L,left=-0.5cm of 9L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (9R)[right of=9L,right=1cm of 9L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (9RT)[right of=9R,right=-0.5cm of 9R]{\texttt{2+k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (10L)[above of=9L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (10LT)[left of=10L,left=-0.5cm of 10L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (10R)[right of=10L,right=1cm of 10L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (10RT)[right of=10R,right=-0.5cm of 10R]{\texttt{$ \vdots $}}; \path[-] (8L) edge node [above]{}(10R); \path[-] (7L) edge node [above]{}(9R); \path[-] (6L) edge node [above]{}(8R); \path[-] (5L) edge node [above]{}(7R); \path[-] (4L) edge node [above]{}(4R); \path[-] (3L) edge node [above]{}(3R); \path[-] (2L) edge node [above]{}(2R); \path[-] (1L) edge node [above]{}(1R); \path[-] (0L) edge node [above]{}(0R); \end{scope} \end{tikzpicture} \end{center}% \end{center} \end{minipage}\begin{minipage}[b]{4cm} \begin{center} % %diag: \begin{center} \begin{tikzpicture}[node distance=2cm] \begin{scope}[node distance=0.5cm]\path node (0L){\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (0LT)[left of=0L,left=-0.5cm of 0L]{\texttt{0}}; \path node (0R)[right of=0L,right=1cm of 0L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (0RT)[right of=0R,right=-0.5cm of 0R]{\texttt{0}}; \path node (1L)[above of=0L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (1LT)[left of=1L,left=-0.5cm of 1L]{\texttt{1}}; \path node (1R)[right of=1L,right=1cm of 1L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (1RT)[right of=1R,right=-0.5cm of 1R]{\texttt{$ \vdots $}}; \path node (2L)[above of=1L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (2LT)[left of=2L,left=-0.5cm of 2L]{\texttt{2}}; \path node (2R)[right of=2L,right=1cm of 2L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (2RT)[right of=2R,right=-0.5cm of 2R]{\texttt{k}}; \path node (3L)[above of=2L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (3LT)[left of=3L,left=-0.5cm of 3L]{\texttt{$ \vdots $}}; \path node (3R)[right of=3L,right=1cm of 3L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (3RT)[right of=3R,right=-0.5cm of 3R]{\texttt{1+k}}; \path node (4L)[above of=3L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (4LT)[left of=4L,left=-0.5cm of 4L]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}1}}; \path node (4R)[right of=4L,right=1cm of 4L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (4RT)[right of=4R,right=-0.5cm of 4R]{\texttt{2+k}}; \path node (5L)[above of=4L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (5LT)[left of=5L,left=-0.5cm of 5L]{\texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (5R)[right of=5L,right=1cm of 5L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (5RT)[right of=5R,right=-0.5cm of 5R]{\texttt{$ \vdots $}}; \path node (6L)[above of=5L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (6LT)[left of=6L,left=-0.5cm of 6L]{\texttt{1+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (6R)[right of=6L,right=1cm of 6L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (6RT)[right of=6R,right=-0.5cm of 6R]{\texttt{k+\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][c]{\ensuremath{\npdotdiv}}1}}; \path node (7L)[above of=6L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (7LT)[left of=7L,left=-0.5cm of 7L]{\texttt{2+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (7R)[right of=7L,right=1cm of 7L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (7RT)[right of=7R,right=-0.5cm of 7R]{\texttt{k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (8L)[above of=7L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (8LT)[left of=8L,left=-0.5cm of 8L]{\texttt{$ \vdots $}}; \path node (8R)[right of=8L,right=1cm of 8L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (8RT)[right of=8R,right=-0.5cm of 8R]{\texttt{1+k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (9L)[above of=8L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (9LT)[left of=9L,left=-0.5cm of 9L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (9R)[right of=9L,right=1cm of 9L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (9RT)[right of=9R,right=-0.5cm of 9R]{\texttt{2+k+\makebox[1.22ex][c]{\ensuremath{\ell}}}}; \path node (10L)[above of=9L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (10LT)[left of=10L,left=-0.5cm of 10L]{\texttt{\makebox[1.22ex][c]{{~}}}}; \path node (10R)[right of=10L,right=1cm of 10L]{\texttt{\makebox[1.22ex][c]{$ \bullet $}}}; \path node (10RT)[right of=10R,right=-0.5cm of 10R]{\texttt{$ \vdots $}}; \path[-] (8L) edge node [above]{}(10R); \path[-] (7L) edge node [above]{}(9R); \path[-] (6L) edge node [above]{}(8R); \path[-] (5L) edge node [above]{}(7R); \path[-] (4L) edge node [above]{}(6R); \path[-] (3L) edge node [above]{}(5R); \path[-] (2L) edge node [above]{}(4R); \path[-] (1L) edge node [above]{}(3R); \path[-] (0L) edge node [above]{}(2R); \end{scope} \end{tikzpicture} \end{center}% \end{center} \end{minipage} \end{center} \end{flushleft} \caption{The graphs of \texttt{protectedAdd}, \texttt{protectedAdd$ \uparrow $}, and \texttt{unprotectedAdd}\label{addGraphsF}} \end{figure}% % %paragraphName: ↑ versus + Our first conference paper{~}\cite{pouillard-pottier-10} contains a mistake that we would like to briefly explain because it emphasizes why it can be interesting to have both \texttt{\makebox[1.22ex][c]{\_{}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{\_{}}} and \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\_{}}} instead of just the latter.% % %paragraphName: protectedAdd Consider the function{~}\texttt{protectedAdd}\index{Code!\texttt{protectedAdd}}, a variant of which we have already encountered under the name \texttt{shiftName\ensuremath{^{\prime}}} (section{~}\ref{convenienceS}){:}% {\nopagebreak } % %code: % %comment: protectedAdd : ∀ {α} ℓ k → (α ↑ ℓ) →ᴺ (α +ᵂ k ↑ ℓ) %protectedAdd ℓ k = protect↑ ℓ (addᴺ k) % ~\\~\vphantom{$\{$}\texttt{protectedAdd\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}protectedAdd\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}protect\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}add\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: protectedAdd graph It is used as a building block in the definition of the function that {``}shifts{''} a term. The leftmost diagram in figure{~}\ref{addGraphsF} depicts its graph, that is, which arguments are mapped to which results.% % %paragraphName: protectedAdd↑ Here, we have ascribed{~}\texttt{protectedAdd}\index{Code!\texttt{protectedAdd}} a very precise type. In the first conference paper, however, the operation \texttt{\makebox[1.22ex][c]{\_{}}+\makebox[0.61ex][l]{\textsuperscript{W}}\makebox[1.22ex][c]{\_{}}} was not available, so we used \texttt{\makebox[1.22ex][c]{\_{}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{\_{}}} instead. Thus, we wanted to define the following variant of{~}\texttt{protectedAdd}\index{Code!\texttt{protectedAdd}}, whose type is less precise{:}% {\nopagebreak } % %code: % %comment: protectedAdd↑ : ∀ {α} ℓ k → (α ↑ ℓ) →ᴺ (α ↑ k ↑ ℓ) %protectedAdd↑ ℓ k = protect↑ ℓ (addᴺ↑ k) % ~\\~\vphantom{$\{$}\texttt{protectedAdd\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}protectedAdd\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}protect\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: protectedAdd↑ graph The graph of this function appears in the middle of figure{~}\ref{addGraphsF}. The edges are the same as in the case of{~}\texttt{protectedAdd}\index{Code!\texttt{protectedAdd}}, but we have added new nodes so as to suggest that the codomain is now larger. The trouble with this less precise type is, it has more inhabitants. In particular, the function{~}\texttt{add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{{~}}k}, which adds \texttt{k} to every name, regardless of whether this name is \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-bound or \texttt{\makebox[1.22ex][c]{\ensuremath{\ell}}}-free, admits this type, whereas it does not admit the earlier, more precise type{:}\index{Code!\texttt{unprotectedAdd}}% {\nopagebreak } % %code: % %comment: unprotectedAdd : ∀ {α} k ℓ → (α ↑ ℓ) →ᴺ (α ↑ k ↑ ℓ) %unprotectedAdd k ℓ = coerceᴺ (⊆-exch-↑-↑′ ℓ k) ∘ addᴺ↑ k % -- this is ok since (α ↑ k) ↑ ℓ ≡ (α ↑ ℓ) ↑ k % -- whereas (α +ᵂ k) ↑ ℓ ≢ (α ↑ ℓ) +ᵂ k % ~\\~\vphantom{$\{$}\texttt{unprotectedAdd\mbox{\hspace{0.50em}}{:}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \forall $}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \rightarrow $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \rightarrow $\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}{\nopagebreak \newline% }\vphantom{$\{$}unprotectedAdd\mbox{\hspace{0.50em}}k\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}{\char `\=}\mbox{\hspace{0.50em}}coerce\makebox[0.61ex][l]{\textsuperscript{N}}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.83ex][c]{$ \subseteq $}-exch-\makebox[1.22ex][c]{$ \uparrow $}-\makebox[1.22ex][c]{$ \uparrow $}\ensuremath{^{\prime}}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}$ \circ $\mbox{\hspace{0.50em}}add\makebox[0.61ex][l]{\textsuperscript{N}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}k{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}--\mbox{\hspace{0.50em}}this\mbox{\hspace{0.50em}}is\mbox{\hspace{0.50em}}ok\mbox{\hspace{0.50em}}since\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{1em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}$ \equiv $\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{1em}}k{\nopagebreak \newline% }\vphantom{$\{$}\mbox{\hspace{1em}}--\mbox{\hspace{0.50em}}whereas\mbox{\hspace{5em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\mbox{\hspace{0.50em}}\ensuremath{\npnotequiv}\mbox{\hspace{0.50em}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{$ \uparrow $}\mbox{\hspace{0.50em}}\makebox[1.22ex][c]{\ensuremath{\ell}}\makebox[1.22ex][r]{$ {)} $}\mbox{\hspace{0.50em}}+\makebox[0.61ex][l]{\textsuperscript{W}}\mbox{\hspace{0.50em}}k{\nopagebreak \newline% }\vphantom{$\{$}}% % %paragraphName: the bug The graph of the function \texttt{unprotectedAdd} appears as the rightmost diagram in figure{~}\ref{addGraphsF}. In the conference paper{~}\cite{pouillard-pottier-10}, we fell into this trap and defined a function (called{~}\texttt{shiftName} there) with the behavior of{~}\texttt{unprotectedAdd}, whereas the intended behavior was that of{~}\texttt{protectedAdd\makebox[1.22ex][c]{$ \uparrow $}}. We did not notice the bug, and indeed were quite confident that there was no bug, because the soundness proof based on logical relations went through. In fact, the proof was correct, but the resulting {``}free theorem{''} did not guarantee that this particular kind of mistake would be ruled out. Indeed, because the {``}generalized import{''} function (which {``}shifts{''} a term) was polymorphic in the source world{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}}, the {``}free theorem{''} did guarantee that this function would deal with \emph{free names} in a correct manner, that is, in an equivariant manner. The {``}free theorem{''} did not guarantee, however, that \emph{bound names} would be correctly dealt with, and indeed our mistake caused a bound name to be incorrectly replaced with another bound name.% % %paragraphName: moral One moral of this story is that, even when the logical relations argument {``}goes through{''}, one must be careful to check that the {``}free theorems{''} do mean what one hopes they mean. Another possible moral is that more precise types can help detect more mistakes; but this requires that the programmer be wise enough to make use of these precise types in the first place.% \section{Related work\label{relatedS}} % %paragraphName: challenge The difficulty of programming with, or reasoning about, names, binders, and $ \alpha $-equivalence has been known for a long time. It has recently received a lot of attention, due in part to the{~}\textsc{PoplMark} challenge{~}\cite{poplmark}. Despite this attention, the problem is still largely unsolved{:} according to Guillemette and Monnier, for instance, {``}none of the existing representations of bindings is suitable{''} \cite{guillemette-monnier-08}.% \subsection{Systems} % %paragraphName: not exhaustive/recent work In the following, we review several systems that are intended to facilitate the manipulation of names and binders. This review is not exhaustive{:} we focus on relatively recent related work. Pouillard{'}s Ph.D. thesis{~}\shortcite{pouillard-12} contains a much more detailed review of the connections between \textsc{NomPa} and several approaches to representing syntax with binders, including nominal signatures \cite{pitts-06}, C$ \alpha $ml{~}\cite{pottier-alphacaml}, \textsc{FreshLib}{~}\cite{cheney-05}, \textsc{Binders Unbound}{~}\cite{weirich-yorgey-sheard-11}, and the Locally Nameless{~}\cite{aydemir-08,chargueraud-11-ln} and Locally Named{~}\cite{sato-pollack-10,pollack-sato-ricciotti-11} representations.% \paragraph{Our previous papers} % %paragraphName: intro This paper combines and extends two conference papers{~}\cite{pouillard-pottier-10,pouillard-11}. Here is a summary of the differences between these papers and the present work and of the path that we have followed.% % %paragraphName: freshlook @ ICFP'10 In the first conference paper, we present an abstract interface for programming with names and binders. By design, this interface does not use any dependent types, so it can be expressed, if desired, in a programming language such as Haskell. We point out that this interface can be implemented either in nominal style or using de Bruijn indices. These two implementations have different cost models. In particular, some operations are no-ops in one implementation, but not in the other. World inclusion, for instance, is a no-op in the nominal model, but is implemented as addition in de Bruijn model. For each of the two implementations, separately, we construct a family of logical relations, and use them to obtain certain theorems for free. For the nominal implementation, in particular, we focus on the type{~}\texttt{Tm} of untyped lambda-terms; we prove that the logical relation at this type coincides with a standard notion of $ \alpha $-equivalence; and we conclude that every function of type{~}\texttt{\makebox[1.22ex][c]{$ \forall $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{\{{}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{\}{}}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}$ \rightarrow $\makebox[1.22ex][c]{{~}}Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} respects $ \alpha $-equivalence (and, in fact, commutes with an arbitrary permutation of the free names).% % %paragraphName: nameless, painless @ ICFP'11 In the second conference paper, the first author reconsiders some of the design decisions of the first paper. In particular, the decision to not use any dependent types, as well as the decision to abstract away the differences between the nominal and de Bruijn implementations, are quite costly{:} they make the system significantly more complex than it could be. Thus, Pouillard decides to reverse these decisions, by taking full advantage of dependent types, and by focusing on the de Bruijn implementation scheme, which in several ways is simpler than the nominal scheme. This allows several simplifications{:} for instance, the distinction between {``}weak{''} and {``}strong{''} links disappears, and the notion of {``}link{''} itself disappears, because, in the de Bruijn implementation, a link from{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}} to{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} is just an equality between{~}\texttt{\makebox[1.22ex][c]{$ \beta $}} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1}. World inclusion becomes a no-op. The resulting system is closely related to earlier treatments of well-scoped de Bruijn indices, but is more precise, thanks to the distinction between the worlds \texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}+\makebox[0.61ex][l]{\textsuperscript{w}}\makebox[1.22ex][c]{{~}}k} and{~}\texttt{\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}\makebox[1.22ex][c]{{~}}k}, and yields stronger guarantees, that is, stronger {``}theorems for free{''}. The logical relations argument is machine-checked. A flaw in the first conference paper is fixed (see section{~}\ref{bugS}).% % %paragraphName: here In the present paper, we stick with dependent types. Furthermore, we point out that there is no need to choose between the nominal approach and de Bruijn{'}s approach. We propose a system where these techniques co-exist, so it is possible for some data structures to use a nominal representation, while others use de Bruijn indices. Furthermore, as demonstrated in Pouillard{'}s Ph.D. thesis{~}\shortcite{pouillard-12}, the system supports other representation techniques, including de Bruijn levels and the Locally Nameless representation. In short, the present system is very expressive and is simpler than the one found in our first conference paper. Its soundness proof involves just one logical relation, and is machine-checked.% % %paragraphName: links In the present approach, it is still possible, if desired, to abstract away the differences between the nominal style and de Bruijn{'}s style. On top of \textsc{NomPa}, one defines the interface of a little library, which advertises an abstract type of {``}links{''} between worlds, together with a small number of operations, such as exporting or importing a name through a link. One provides two implementations of this interface, one in nominal style, the other in de Bruijn style. Client code can then be written against the abstract interface, independently of which implementation is eventually chosen. More details appear in Pouillard{'}s Ph.D. thesis{~}\shortcite{pouillard-12}.% \paragraph{\textsc{FreshML} and Pure \textsc{FreshML}} % %paragraphName: FreshML FreshML \cite{shinwell-03} extends ML with primitive types for names (known as atoms) and name abstractions. The semantics of \textsc{FreshML} dictates that pattern matching against a name abstraction silently replaces the bound atom with a fresh atom. \textsc{FreshML} guarantees that {``}name abstractions cannot be broken{''}, that is, two $ \alpha $-equivalent terms cannot be distinguished. Nevertheless, \textsc{FreshML} is unsafe{:} it is possible for a name to escape its scope. Put another way, \textsc{FreshML} is impure{:} name generation is an observable side effect. There are functions which, when applied twice to the same argument, produce observably different results.% % %paragraphName: Pure FreshML Pure \textsc{FreshML}{~}\cite{pottier-lics-07} imposes additional static proof obligations, which ensure that freshly created atoms do not escape their scope, and correspond to Pitts{'} \emph{freshness condition for binders} \shortcite{pitts-06}. Because these proof obligations are expressed in a specialized logic, they can be discharged automatically. Because it is safe, Pure \textsc{FreshML} can be implemented either using atoms (such as the original \textsc{FreshML}) or using de Bruijn indices. This is an implementation choice, which the programmer need not know about.% % %paragraphName: exportTm? runtime checks In contrast with Pure \textsc{FreshML}, the approach proposed in the present work does require more runtime checks. For instance, the operation{~}\texttt{exportTm?} (section{~}\ref{fruitS}) fails if its argument contains a free name that cannot be exported, whereas Pure \textsc{FreshML} requires a static proof that no such name occurs in the term that is exported. Of course, in Pure \textsc{FreshML}, inserting an explicit dynamic check into the program is sometimes the only way of meeting this static proof obligation. In that case, the two approaches are ultimately equivalent.% % %paragraphName: non primitive name abstraction In Pure \textsc{FreshML}, name abstraction is a primitive notion, and the fact that deconstructing an abstraction automatically freshens the bound atom is used to guarantee that all terms effectively live in a single world. In our work, in contrast, name abstraction is explained in terms of more basic notions, and it is possible to deconstruct a name abstraction without substituting a fresh name for the bound name. This leads to a finer-grained understanding of binding, to greater expressiveness, and, in some cases, to greater runtime efficiency.% \paragraph{Nominal System T} % %paragraphName: nomSysT Pitts{'} Nominal System{~}$ {T} ${~}\shortcite{pitts-10} follows the tradition of \textsc{FreshML} and guarantees that name abstractions cannot be violated. In order to ensure that names do not escape their scope, Pitts uses a dynamic technique{:} the{~}$ \nu $ construct, which can be applied to any term, turns every name occurrence that is about to escape its scope into a harmless {``}anonymous name{''}, known as{~}\texttt{new}. One potential advantage of this approach is that the application of{~}$ \nu $ to a term can be lazily evaluated, whereas our{~}\texttt{exportTm?} operation requires eagerly traversing the entire term in order to determine whether it succeeds or fails.% % %paragraphName: emulating nomSysT We can emulate Pitts{'} approach on top of our system by introducing a special value that represents{~}\texttt{new}. This does not require any change to \textsc{NomPa}. We define the type{~}\texttt{Name?\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} as{~}\texttt{Maybe\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}}, and let{~}\texttt{new} be{~}\texttt{nothing}. (Another approach is to define{~}\texttt{Name?\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} as{~}\texttt{Name\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \uparrow $}1\makebox[1.22ex][r]{$ {)} $}} and{~}\texttt{new} as{~}\texttt{zero\makebox[0.61ex][l]{\textsuperscript{N}}}.) Most of our operations on names can then be easily lifted to the type \texttt{Name?}. In particular, the lifted version of{~}\texttt{export\makebox[0.61ex][l]{\textsuperscript{N}}?} receives the type{~}\texttt{Name?\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Name?\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} and can thus be viewed as a total function over possibly undefined names. The lifted version of{~}\texttt{exportTm?} receives the type{~}\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][l]{$ {(} $}b\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{\ensuremath{\triangleleft}}\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}\makebox[1.22ex][r]{$ {)} $}\makebox[1.22ex][c]{{~}}$ \rightarrow $}{ }\texttt{Tm\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \alpha $}} and is thus a total function. Of course, one must keep in mind that terms can now contain occurrences of the undefined name \texttt{new}. In this approach, there is no direct equivalent of the operation{~}\texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}}, since the type \texttt{Name?\makebox[1.22ex][c]{{~}}\makebox[1.22ex][c]{$ \emptyset $}} is inhabited by{~}\texttt{new}.% \paragraph{Elphin, Delphin, Beluga, Beluga$ ^{\mu} $} % %paragraphName: elphin, delphin, beluga Elphin{~}\cite{elphin-05}, Delphin{~}\cite{delphin-08,delphin-09}, and Beluga{~}\cite{pientka-08} are closely related to one another in several ways. These programming languages have separate data and computation layers. The types in the data layer are built out of LF types and terms.% % %paragraphName: elphin limitations Elphin only has a limited way to include types from the data layer in the computation layer. Both Delphin and Beluga have contexts, but handle them differently. Delphin deals with an implicit {``}current context{''}, while Beluga has explicit contexts. Delphin allows incremental changes of the current context using{~}\texttt{\makebox[1.22ex][c]{$ \nu $}}, whereas Beluga combines contexts and LF objects at the boundary between data and computation.% % %paragraphName: contrasts At the data level, Elphin, Delphin, Beluga provide substitution and higher-order matching as primitive operations. This ambitious approach can eliminate some boilerplate code, at the cost of a complex meta-theory. By contrast, the meta-theory of our proposal is very simple, as it only extends \textsc{Agda}{'}s existing logical relation with a few new abstract types and operations. In principle, we should be able to eliminate some of the boilerplate via generic programming, following Cheney{'}s \textsc{FreshLib}, Licata and Harper, and \textsc{Binders Unbound}.% % %paragraphName: belugamu Beluga$ ^{\mu} ${~}\cite{cave-12} extends Beluga with richer computational types. It allows the definition of recursive data types not only in the data layer, but in the computation layer as well. These data types can be indexed by LF objects of the data layer. While substitution comes for free in the data layer, it has to be defined by the user in the computation layer. Incidentally, Cave and Pientka use a version of our system in order to establish the meta-theoretic properties of Beluga$ ^{\mu} $ in the \textsc{Coq} proof assistant. They use a simplified version of the {``}links{''} found in our first conference paper{~}\cite{pouillard-pottier-10} which corresponds to the {``}little link library{''} that we have mentioned above.% \paragraph{Well-scoped de Bruijn indices} % %paragraphName: wdbis We have reviewed in section{~}\ref{deBruijnS} how type-theoretic machinery (such as nested algebraic data types, generalized algebraic data types, or dependent types) can be used to ensure that every de Bruijn index remains within range{~}\cite{bellegarde-94,bird-paterson-99,altenkirch-reus-99}. In fact, dependent types can be used to encode not only the lexical scoping discipline, but also the type discipline of an object language{:} see, for instance, Chen and Xi{~}\shortcite{chen-xi-pepm-03,chen-xi-icfp-03} and Chlipala \shortcite{chlipala-07}. This is an aspect that we did not investigate and leave for future work. De Bruijn indices are, by nature, very low-level{:} it is desirable to build more abstract representations on top of them. For instance, Donnelly and Xi{~}\shortcite{donnelly-xi-05} define an algebraic data type of terms that is based on well-scoped de Bruijn indices, but is indexed with a higher-order abstract syntax representation of terms. Licata and Harper{'}s system{~}\shortcite{licata-harper-09} is also implemented on top of well-scoped de Bruijn indices. Our system exposes de Bruijn indices, but offers stronger guarantees than conventional systems based on well-scoped de Bruijn indices. If world polymorphism is appropriately exploited, the system can guarantee not only that every index is within range, but also that free variables are treated abstractly (section \ref{usingParam}), which implies that certain programming errors, such as {``}forgetting to shift{''} a free variable, can be detected by the type system.% \paragraph{Licata and Harper{'}s system} % %paragraphName: contrasts Licata and Harper{~}\shortcite{licata-harper-09} aim to provide substitution for free when possible, whereas we do not explicitly explore this aspect. They impose the use of well-scoped de Bruijn indices to the programmer, whereas our {``}names{''} are more flexible and can be used as atoms or as de Bruijn indices.% % %paragraphName: similarities This said, there are numerous similarities between the two systems. Both keep track of the context, or world, within which each name makes sense. Both offer flexible ways of parameterizing or quantifying types over worlds. Both offer ways of moving data from one world to another{:} Licata and Harper{'}s weakening and strengthening respectively correspond to our import (coerce) and export operations. Both systems support first-class computational functions. Not all functions can be imported or exported, but some can{:} for instance, in both systems, the example of normalization by evaluation (section{~}\ref{nbeS}), which requires importing a function into a larger world, is made type-correct by planning ahead and making this function polymorphic with respect to an arbitrary world extension.% \paragraph{\textsc{FreshLib} and \textsc{Binders Unbound}} % %paragraphName: freshlib and binders unbound Like us, Cheney{~}\shortcite{cheney-05} (\textsc{FreshLib}), Weirich et al.{~}\shortcite{weirich-yorgey-sheard-11} (\textsc{Binders Unbound}) strive to develop libraries that facilitate programming with names and binders inside a mainstream programming language (in these cases, Haskell). The facilities that they offer in order to describe data structures with names and binders are quite powerful. For instance, \textsc{Binders Unbound} is able to express {``}telescopes{''}, which are analogous to the one-hole contexts of section{~}\ref{elaborateS}. \textsc{Binders Unbound} is more recent than \textsc{FreshLib}, and, as far as we understand, subsumes it. \textsc{Binders Unbound} is less expressive than our system (fewer data structures can be defined) and can be less efficient (some operations, such as traversing a term, are more costly). On the other hand, using a more restricted data description language makes generic programing easier{:} code for traversal, substitution, etc. can be automatically generated, whereas, in our system, generic programming remains a topic for future study. Pouillard{~}\shortcite{pouillard-12} gives a more detailed account of the connection between \textsc{Binders Unbound} and our system, including an encoding of the former into the latter.% \paragraph{Moving across representations} % %paragraphName: we move across representations It is arguably desirable to be able to offer several choices of representation within a single system, and to be able to migrate from one representation to another. Our system supports multiple representation styles, including the nominal representation (section{~}\ref{nompaIface}), de Bruijn{'}s representation (section{~}\ref{napaS}), and more \cite{pouillard-12}. Furthermore, our implementation of normalization by evaluation (section{~}\ref{nbeS}) illustrates how to move back and forth between {``}syntactic{''} name abstractions and {``}semantic{''} name abstractions in the style of higher-order abstract syntax.% % %paragraphName: connection with Atkey Atkey and co-authors{~}\cite{atkey-hoas-09,atkey-lindley-yallop-09} investigate how to move back and forth between higher-order abstract syntax and de Bruijn indices. The translation out of higher-order abstract syntax produces well-scoped de Bruijn indices, but the proof of this fact is meta-theoretic. Atkey uses Kripke logical relations to argue that the current world at the time of application of a certain function must be larger than the world at the time of construction of this function. This seems somewhat related with our use of bounded polymorphism in the definition of semantic name abstractions (section{~}\ref{nbeS}). An exact connection remains to be investigated.% \subsection{Questions} % %paragraphName: questions One traditionally distinguishes several broad approaches to the problem of names and binders, which employ seemingly different tools, namely{:} atoms and atom abstractions; well-scoped de Bruijn indices; higher-order abstract syntax. We believe that this distinction can be superficial. In fact, our work presents strong connections with all three schools of thought. Perhaps more important are the following questions{:}% \paragraph{\emph{Can $ \alpha $-equivalent terms be distinguished?}} % %paragraphName: all except bare de Bruijn and plain nominal Except for the bare nominal and bare de Bruijn approaches (sections{~}\ref{bareNominal} and{~}\ref{bareDeBruijn}), all of the systems that we have discussed guarantee that two $ \alpha $-equivalent terms cannot be distinguished. These systems offer adequate encodings of nominal terms and guarantee that {``}the identity of a bound name cannot be observed{''}.% \paragraph{\emph{What hygiene properties are enforced by the system?}} % %paragraphName: other approaches The most basic hygiene property is the guarantee that $ \alpha $-equivalent terms cannot be distinguished. This is a fairly weak property{:} some system offer further guarantees. In \textsc{FreshML}{~}\cite{shinwell-03} name generation is an observable effect. The same is true of several other approaches, including C$ \alpha $ml{~}\cite{pottier-alphacaml}, \textsc{Binders Unbound}{~}\cite{weirich-yorgey-sheard-11}, and the Locally Nameless{~}\cite{aydemir-08,chargueraud-11-ln} and Locally Named{~}\cite{sato-pollack-10,pollack-sato-ricciotti-11} approaches. In other words, in these approaches, applying a function twice to the same argument can produce distinct results. Nominal System{~}$ {T} ${~}\cite{pitts-10} repairs this problem by dynamically detecting that an atom is about to escape and by turning it into a harmless {``}anonymous atom{''}. Systems based on well-scoped de Bruijn indices enforce the invariant that every index is within range, that is, every name refers to some binding site. However, this alone does not imply that indices are correctly adjusted where needed, or that comparisons between names are allowed only when they make sense. In systems based on higher-order abstract syntax, and in Pure \textsc{FreshML}{~}\cite{pottier-lics-07}, name manipulation is hygienic by design{:} this is built in the syntax and semantics of the programming language.% % %paragraphName: our approach In the present paper, hygiene is built in at a very low level. We provide a small number of abstract types, such as{~}\texttt{Binder} and{~}\texttt{Name}, together with a small number of operations. These operations are restricted on purpose{:} for instance, comparing two binders for equality is disallowed; comparing two names for equality is permitted only if they inhabit a common world. Through logical relations and parametricity, we are able to explore the consequences of these restrictions and to find out which hygiene properties can be expected of a well-typed program. In particular, we guarantee that two $ \alpha $-equivalent terms cannot be distinguished and that functions turn $ \alpha $-equivalent arguments into $ \alpha $-equivalent results. These results hold because we consider that, by definition, {``}$ \alpha $-equivalence{''} at type \texttt{$ \tau $} is the logical relation \texttt{\makebox[1.22ex][c]{\ensuremath{\llbracket}}$ \tau $\makebox[1.22ex][c]{\ensuremath{\rrbracket}}}, and because parametricity guarantees that every well-typed program inhabits the logical relation. We do check that our definition of $ \alpha $-equivalence corresponds to the {``}standard{''} notion of $ \alpha $-equivalence at type{~}\texttt{Tm} (section{~}\ref{tmAlphaEquivS}) and more generally at every type that encodes a nominal signature in the sense of Pitts{~}\shortcite{pitts-06}.% \paragraph{\emph{Is there a type of names, or do names inhabit every type?}} % %paragraphName: positive and negative In the {``}first-order{''} systems, there is a dedicated type of names. This includes the \texttt{Fin} approach to de Bruijn indices, the Locally Nameless and Locally Named approaches, \textsc{FreshML}, Nominal System{~}$ {T} $, C$ \alpha $ml, \textsc{Binders Unbound}, and the present work. Names inhabit this type and none other. In {``}higher-order{''} systems, such as Delphin and Beulga, there is no fixed type of names. Instead, a name can inhabit any type of the data layer.% \paragraph{\emph{Does the system distinguish data and computation layers?}} % %paragraphName: answer Elphin, Delphin, Beluga, Beluga$ ^{\mu} $ clearly distinguish two layers. The data layer is restricted and does not have computational functions. In many of the systems that use code generation or generic programming, including C$ \alpha $ml, \textsc{Binders Unbound}, and several implementations of the Locally Nameless and Locally Named approaches, algebraic data types with binding structure are not allowed to contain computational functions, so there are effectively two layers as well. Pure \textsc{FreshML} does not support first-class functions at all. \textsc{FreshML} and its implementation \textsc{Fresh OCaml} do allow computational functions to appear within data. The only generic operation that is provided is name swapping. Similarly, Nominal System{~}$ {T} $ supports first-class functions and name swapping, but is not implemented. In Licata and Harper{'}s work{~}\shortcite{licata-harper-09}, data and computation can also be mixed. However, they are both part of a {``}universe{''} which is then interpreted in terms of the computation types of the host language.% \paragraph{\emph{At which types can substitution be defined? Does it come {``}for free{''}?}} % %paragraphName: yes for elphin, delphin, and beluga In Elphin, Delphin, and Beluga, substitution comes {``}for free{''} at every type of the data layer. This is the reason why there is a data layer in the first place. In Beluga$ ^{\mu} $, substitution comes for free in the data layer but must be defined by the user (when this makes sense) in the computation layer.% % %paragraphName: freshml... In \textsc{FreshML}, name swapping comes for free, but it is up to the user to define substitution. Similarly, in C$ \alpha $ml, a code generator produces the definition of several operations, including renaming, but not substitution. In \textsc{Binders Unbound}, substitution is obtained via generic programming for a family of types that does not include functions. In Licata and Harper{'}s work, a generic definition of substitution is available at many (albeit not all) types.% % %paragraphName: our system In our system, renaming and substitution are defined by the user when this makes sense. As shown in Pouillard{'}s thesis{~}\shortcite{pouillard-12}, a wide range of other systems, including C$ \alpha $ml and \textsc{Binders Unbound}, can be embedded in our system. It should be possible to define generic operations for the subset of our types that lie in the image of these embeddings.% \paragraph{\emph{How does the system keep track of the context or world in which a name makes sense?}} % %paragraphName: yes for... In Pure \textsc{FreshML} and in Nominal System{~}$ {T} $, there is effectively just one world, within which every name makes sense; static or dynamic checks guarantee that no confusion can arise. In Elphin, Delphin, or in Licata and Harper{'}s system, the meaning of types is relative to a {``}current context{''}, and a number of modalities are provided to discard the current context, extend it with one new name, etc. In Beluga and Beluga$ ^{\mu} $, contexts are explicit{:} a data-layer type, once annotated with a context, becomes a computation-layer type. In the present work, worlds are explicit, and are built into algebraic data type definitions by the programmer. There is no notion of a {``}current world{''}{:} multiple worlds can co-exist, and mechanisms are offered for transporting names (or whole data structures) from one world to another.% \paragraph{\emph{Which high-level operations are involved in the semantics?}} % %paragraphName: complexity of the semantic operations The semantics of \textsc{FreshML}, Pure \textsc{FreshML}, and Nominal System{~}$ {T} $ involves renaming. The Locally Nameless and Locally Named approaches, as well as \textsc{Binders Unbound}, involve {``}open{''} and {``}close{''} operations which can be viewed as renamings of a particular kind. The semantics of Elphin, Delphin, Beluga, and Beluga$ ^{\mu} $ involve higher-order matching. In the present work, as well as in Licata and Harper{'}s work, no costly operations are built into the semantics; high-level operations, such as \texttt{exportTm?} and \texttt{shiftTm\makebox[0.61ex][l]{\textsuperscript{D}}}, are programmed explicitly or obtained via generic programming.% \section{Conclusion and future work\label{conclusionS}} % %paragraphName: practical Our contributions are practical and fundamental. On the practical side, we have presented a library, written in \textsc{Agda}, for programming with names and binders. This library is economical{:} it defines a relatively small number of abstract types and operations. It is expressive{:} it offers multiple ways of representing conventional syntax and supports the definition of complex data structures that involve binding. It is sound{:} this has been mechanically checked.% % %paragraphName: fundamental On the fundamental side, we re-use the logical relation defined for \textsc{Agda} by Bernardy et al.{~}\shortcite{bernardy-10} and extend it so as to mechanically obtain a definition of {``}$ \alpha $-equivalence{''} at every type. This includes complex algebraic data types as well as types that involve computational functions. We show how the {``}free theorems{''} that concern certain world-polymorphic functions provide guarantees about well-typed client code.% % %paragraphName: connection We believe that this work establishes numerous connections between three schools of thought that are sometimes considered separate, namely the {``}nominal{''}, {``}de Bruijn{''}, and {``}higher-order abstract syntax{''} schools. Although the first part of this paper (sections{~}\ref{introNominal} to{~}\ref{nompaSoundnessS}) relies on a {``}nominal{''} intuition, the second part (sections{~}\ref{deBruijnS} to{~}\ref{napaRel}) shows that it does not take much to add support for de Bruijn indices. Furthermore, our normalization by evaluation algorithm (section{~}\ref{nbeS}) shows how to work simultaneously with {``}syntactic{''} name abstractions in the style of the {``}nominal{''} school and with {``}semantic{''} name abstractions in the style of higher-order abstract syntax.% % %paragraphName: many avenues There are many avenues for future work.% % %paragraphName: inclusion inference We would like to make our library easier to use. In particular, we would like to be able to automatically construct most of the world inclusion witnesses that are needed in order to move a name or a term from a world to another. We hope that \textsc{Agda}{'}s experimental reflection mechanism can be used for this purpose. % % %paragraphName: generate traversal We have illustrated how hand-written generic traversal functions help avoid code duplication. We would like to go one step further by giving generic definitions of these functions for a fixed universe of types.% % %paragraphName: side-effects We would like to study how to support the presence of side effects. One could attempt to do this either by remaining within \textsc{Agda} and modeling effects as monads or by stepping out of \textsc{Agda} and extending an imperative programming language with operations on names and binders inspired by our library.% % %paragraphName: reasoning We would like to explore how one can reason about (that is, prove properties of) the programs that use our library. The library currently advertises a number of abstract types and operations. It seems that, in order to allow a client to reason, the library should also publish a number of laws, or properties, that describe the behavior of these operations.% % %paragraphName: extraction Although we have claimed informally that {``}worlds can be erased{''}, we have not carried out a formal proof of this claim. One would be tempted to define an alternative implementation of our library where \texttt{World} is the unit type and to prove that this implementation behaves in the same way as the implementation presented here. This is probably not as easy as one might think, though. If \texttt{World} is the unit type, then there is no way to implement \texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}} in a total language. One must somehow implement a version of \texttt{\makebox[1.83ex][c]{$ \neg $}Name\makebox[1.22ex][c]{$ \emptyset $}} that always fails at runtime, and argue that a well-typed program will never encounter a failure.% % %paragraphName: efficiency In order to achieve reasonable runtime efficiency, it would also be desirable to study how names can be implemented by machine integers and how {``}coercion{''} functions such as{~}\texttt{coerceTm}, whose semantics is the identity, can be optimized away. One might also wish to study whether our {``}name supplies{''} can be erased and replaced with a global, effectful {``}gensym{''} operation.% % %paragraphName: not only scopes Finally, although we have focused exclusively on {``}well-scoped syntax{''}, it would be desirable to study how to work with syntax that is both {``}well-scoped{''} and {``}well-typed{''} by construction.% \bibliographystyle{jfp} \bibliography{../../local,../../npouillard} \end{document}