Refactoring

Binder:

In λ-calculus, a binder is a λ abstraction that introduces a new variable. so for example λx.body introduces a variable x hence λx is a binder for all the xs that are in body. To convert a named lambda term into a deBrujin indexed nameless expression, for each variable, we have to replace it with the (nearest) distance of the binder that binds this variable. So if the nearest binder of x is THE nearest binder, we give it an index 0, if the nearest binder of x is the second near binder, we give it an index 1 and so forth.

So, let's write a named expression in deBrujin form:
consider

λz.(λy.y(λx.x))(λx.zx)

for each variable, we have to find the nearest lambda on the left that binds it. First of all, λz is the outermost and only binder for z. if we notice closely, the above expression looks something like λz.(t1)(t2), that is we are talking about a function that takes z as the argument and returns an application (t1)(t2). which means that any z in (t1) or (t2) are bound by this outer lambda. Notice t2=λx.zx, so λz binds t2, and in t2 λx bind zx. hence, the nearest binding of z is two levels deep, (and using zero indexing) the index of z is hence 1.
using this logic over and over again, seeing the nearest lambda that binds a variable, and how deep it is, we can re-write the expression in deBrujin form.

λ. (λ. 0 (λ. 0))(λ. 1 0)

how do we convert it back? it's pretty straight forward, we just give each binder a variable name, and use distances given by the indices to re-name the indices.

but now we have the mysterious shift operator:

upShift

for any nameless term t, the upshift of t by k with cutoff c, written ckt is defined as follows:
if t is an index: if tc then t+k. if t<c then t.
if t is a lambda abstraction λt then λc+1kt.
if t is an application (t1 t2) then (ckt1 ckt2).

Substitution:

The rough idea of substitution is that functions are only dependent on how the transform an input. Not on what the inputs are named or what they look like. So we want to have some rules to re-write variables in such a way that a re-write (or substitution) is functionally equivalent to its original.

usually, in named form, a lambda abstraction looks like u=λx.t, where t is any term. in nameless (deBrujin index) form, u=λ.t. in any even, we see that all x that appear in t are bound by the outer lambda. similarly, in the deBrujin form u, there might be indices who's nearest binding is in fact this outer lambda.
The key thing to internalize is that we are not substituting a variable NAME anymore. deBrujin indices are not just names. They represents distances from the nearest lambda that binds them.
but there are more issues here:
Let us look at some substitutions in the case of named expressions.

[xs]x=s[xs]y=y if xy[xs](λy.t1)=λy[xs]t1[xs](t1t2)=([xs]t1)([xs]t2)

for example [xy]λx.x our result is λx.y which is quite funny, as it changes the identity function into a constant function.

Hence, it should be a rule that once we encounter a variable name in binding,we can't substitute it. so we account for that.

[xs]x=s[xs]y=y if xy[xs](λy.t1)=λy[xs]t1if xy[xs](λy.t1)=λyt1if x=y[xs](t1t2)=([xs]t1)([xs]t2)

Next, consider [xz]λz.x: this results in λz.z. This time we morphed a constant function into the identity function. In the general substitution [xs]λy.t, the free variables in s becoming bound when substituting in t is called "capture". let's correct that.
[xs]x=s[xs]y=y if xy[xs](λy.t1)=λy[xs]t1if xy and yFV(s)[xs](λy.t1)=λyt1if x=y[xs](t1t2)=([xs]t1)([xs]t2)

Whenever the above definition doesn't give us an answer, we can use alpha conversion to fully re-name all bound variables appropriately.

Now, we need to figure out the analog of the substitution for deBrujin expressions.

In order to do this, we need to develop deBrujin expressions a little more.

The first thing we need is the definition of a term

Term

a term is an element of T: the smallest family of sets {T0,T1} such that:
An index k is in Tn if 0k<n
If a term tTn and n>0, λ.tTn1
if terms t1,t2Tn then (t1 t2)Tn

Essentially, each Ti represents the set of all terms that have at most i free-variables.

when we were talking about binders, we knew how to set index of a variable, by finding the distance of the nearest binder that binds that variable. What about free variables? well, for that, we need a context.

Context

let V be the set of variable names in named lambda calculus.
The context Γ select n+1 names xn,xn1..x0 from V and assigns them indices n,n1,..0 respectively. (xii),

The rough idea is that having an n+1 length context allows us to write any term in {T0,T1,Tn+1} cause we do have n+1 free variables.
Let's setup a context for our free variables: Γ=e4,d3,c2,b1,a0.
now, lets try to convert λx.ax into deBrujin form. we know that the nearest binder to x is at distance 0, so x0 but a0 as well? NOT SO FAST! the moment we go inside the "context" of a binder, λx.body, we know that x can appear in the body such that λx is it's nearest binder and at a distance 0. so this means that inside the context of this binder, all our indices free variables must be incremented.
so x0 and a1, hence written as λ.1 0.

So now, we can build up our Substitution in deBrujin form.
Remember that we can only substitute free variables. let Γ be an n length context. let j be the index of a free variable in Γ that we want to replace by a term s, in the term λt.
so this lambda binds some index. whatever it binds, assuming there is no more λ's in t, that bound index is 0. and inside the lambda, the free variable j is actually j+1. Moreover, in s, we need to ensure all the free variables are incremented, so we need to upshift it.

The cutoff c in the upshift operator ck makes a lot of sense right now. suppose s=λs, then of course, the context inside the lambda (ie in s) has all it's free variables indices from 1 to n instead of 0 to n1 in the outer context Γ. so if we want to upshift all the free variables in λs
we should up shift variables 1..n in s and ignore 0 as the lambda binds it.
Therefore, it makes sense that 01λs=λ11s.

So now, we finally have made it.

Substitution in DeBrujin expressions

Let Γ be an n length context for free variables, and t,sTn (notice Tn contains Ti for in). Then the substitution of a free index j with the term s in the term t is defined recursively as follows:
If t is an index, [js]t={s  if  t=j  else  t}
if t=λt: [js]λt=λ[j+101s]t
if t=(t1 t2): [js](t1 t2)=([js]t1 [js]t2)

The great beta reduction:

So, here we are, and now we want to write the β reduction as a substitution in deBrujin expressions.
so we are given a context of length n, Γ, and a lambda abstraction λb, a term v and we need to evaluate (λb)v which is the beta reduction. so in a beta reduction, we always substitute the index bound by the outermost lambda. It is pretty safe to say that we are substituting the index 0 in b with v. But there is a slight catch. if b,vTn, then we see that the context of free variables in b is upshifted because it is inside a lambda.
but the context of free variables, v is still the global context Γ. so we need to ensure that we upshift v before substituting.

so we have something along the lines of [01v]b. The second issue is, that the beta reduction actually removes the outermost lambda, which means that it unbinds some variable. Which then means that we need to downshift the context.
so the final beta reduction is 1[01v]b.

jumping through hoops, the kth beta reduction:

beta reduction

let v,λb be deBrujin terms in some n context Γ. The beta reduction of λb at v is: $$ \uparrow^{-1}[0 \mapsto \uparrow^1v]b $$
the k beta reduction is (denoted as βk(b,v)):

k1[kk+1v]b

Lets try to notice something, suppose b=λb. Try simplify the expression \uparrow^{-1}[0 \mapsto \uparrow{#1v}]\lambda b':

1[01v]λb=1λ[111v]b=λ11[12v]b

Wow! if b has a chain of k lambdas, then then the beta reduction of λb at v is equivalent to λλ..k timesλk1[kk+1v]bk

Version space:

Version space

a version space is one of the following:
An index i
An abstraction λv where v is a version space
An application (f x) where f,x are version spaces.
A union +V where V is a set of version spaces.
The set of all lambda expressions Λ
The empty set

We are back to the paper now, and are again in thinking about our deBrujin expressions as programs. Now basically, a version space for a program, efficiently and compactly maintains refactorings of a program. (we will explore this in detail later)

Now, we want to define an operator S0(u) that takes in version spaces and spits out sets of "substitutions" {ab} between two version spaces (note that a,b,u are version spaces).
But these substitutions are not the substitutions defined earlier, the idea is that these represent refactorings of programs in the version space u. in particular if aa and bb are programs, then the beta reduction of λb at a: β0(b,a) is a program in u. (a notion of consistency)

Moreover, if a and b are programs, and we have that β0(b,a)u, then it must mean that there are version spaces a,b such that {ab}S0(u) and aa,bb. (a notion of completeness)

But as is the nature of inductive definitions, we actually want to define Sk. TAKE THE DOWNSHIFT OPERATOR NOW!

downshift

cki=i, when i<ccki=(ik), when ic+kcki=, when ci<c+kckλb=λc+1kbck(fx)=(ckfckx)ckV={ckvvV}ckv=v, when v is a primitive or  or Λ

We can think of shifting operations applied to version spaces (which are basically sets of programs) as applying it to to each program in that set.

kth refactor operator

Sk(v)={0kvk}{ if v is primitive: {Λv} if v=i and i<k:{Λi} if v=i and ik:{Λ(i+1)} if v=λb:{vλb:vbSk+1(b)} if v=(fx):{v1v2(fx):v1fSk(f),v2xSk(x)} if v=V:vVSn(v) if v is : if v is Λ:{ΛΛ}

Lemma 1. Let e be a program or version space and n, c be natural numbers. Then \uparrow_{n+c}^{-1} \uparrow_c^{n+1} e=\uparrow_c{#n} e, and in particular n1n+1e=ne.

Lemma 2. Let e be a program or version space and n, c be natural numbers. Then cncne=e, and in particular nne=e.

Consistency of Sk

If (ab)Sk(v), then for all programs aa and bb, the k beta reduction of b at a, k1[kk+1a]bv.

proof: We first deal with the case that b=k. in this case, a = \downarrow_{0}{#kv} let v be any program in v. we know that arbitrary aa can be written as a=0kv for some vv. In particular, aaa=0kv: vv. moreover, b=k. hence: $$ \uparrow_{k}^{-1}[k \mapsto \uparrow^{k+1}a']b' = \uparrow_{k}^{-1}[k \mapsto \uparrow^{k+1}\downarrow_{0}^kv']k = \uparrow^{-1}_{k}(\uparrow^{k+1}\downarrow^kv')$$
invoking the above lemmas, we notice that the rightmost expression evaluates to v.

Now, for the other cases, we use structural induction:

k1[kk+1a]i+1=k1(i+1)=i$$(as$i+1>k$),andwearedone.if$v$isaprimitive,wedealwith$a=Λ$and$b=b=v$.pickarbitrary$aΛ$.weget:$$k1[kk+1a]v=k1v=v$$(weassumeaprimitiveisnotadeBrujinindexoranyotherthing,IDKWHY(gottainvestigate))Ithinkitsbecausetheupshiftanddownshiftforprimitivesor$$or$Λ$isequaltoitself.if$v=λt$,wearedealingwiththesubstitution$(uλp)$where$(up)Sk+1(t)$.Thereisacleverhypothesistoprovehere:weclaimthatforall$uu$and$pp$,$k+11[k+1k+2u]pt$.Thisisthenotionofconsistencyof$Sk+1$.Thereasonwecandothis,isbecauseif$t$isntalambda,alltheothercaseswillsufficetoshowconsistencyof$Sk+1$.otherwise,if$t$isalambda,thenwecanrecursivelycomebacktothiscase:anyexpressionisfiniteandiseventuallynotalambda,sotheconsistencybubblesbackto$Sk+1$.(thiscanbeshowviainduction)Now,wenotice$$k+11[k+1k+2u]ptk1[kk+1u]λpλt=v$$Hencewearedone.if$v=(f x)$thenwedealwith$(v1v2(g y))$where$v1gSk(f)$and$v2ySk(x)$.Nowassumerecursivelythat$(Sk)$isconsistentforothercases,orrecursebacktothiscase(therecanonlybeafinitenumberofapplicationsintheexpression$v$)Nowpick$gg$,$yy$and$pv1v2$.$k1[kk+1p]gf$and$k1[kk+1p]yx$.hence,combining,$$k1[kk+1p]g(f x)=v$$andwearedone.if$v=$or$v=Λ$,orunionwearedonevacuouslyorbyrecursion/induction.$$>[!theorem]$Sk$iscomplete>let$v$beaversionspace,and$a$,$b$beprograms.Thenif$k1[kk+1a]bv$thenthereexistsversionspaces$a,b$suchthat$aa, bb$and$(ab)Sk(v)$.$proof:$Wewillfirstdealwiththecasethat$b=k$.Then,wehavethat$k1[kk+1a]kv$.Hence,$k1k+1av$therefore$kav$,hence$kkakv$.Therefore$akv$.Giventhat$(kvk)Sk(v)$,wearedone.Wewillfurtherdealwiththeothercasesviastructuralinduction.if$v=i$,then$k1[kk+1a]b=i$Andbyexaminingthedefinitionofsubstitution,itisclearthat$b$mustbeanindex,and$bk$followsaswehavealreadydealtwiththatcase.Therefore,$k1b=i$.Wecanfigureoutwhat$b$is:if$i<k$,ithastobethat$b=i$.if$ik$,ithastobethat$b=i+1$fortheaboveequationtohold.Inthefirstcase,invoke$(Λi)Sk(v)$andinthesecond,$(Λi+1)Sk(v)$andwearedone.if$v=λt$then$k1[kk+1a]bλt$forsome$vv$.since$bk$wecantsubstitute$b$foralambdaform,and$b$isanyotherindexorapplication,itsimplydoesntwork.Therefore$b=λc$.Hence,$$λk+11[kk+2a]cλtk+11[kk+2a]ct$$Whichmeansthatinductively,$(ac)Sk+1(t)$suchthat$aa$and$cc$(thisholdsbecause$t$containsfinitelymanylambdaabstractions,soeventuallyconsistencywilldefertosomeothercasewhichwehaveproved,andbubblebackwardtoshowthat$Sk+1$isconsistent,usingthiscasesproofeachtimethereisanewlambda)Hence,bydefinitionof$Sk$,$(aλc)Sk(λt)$and$aina$and$b=λcλc$.if$v=(f x)$thensince$bk$againwecantsubstituteanapplicationfor$b$,and$b$cantbeanyotherindex,oraunionoralambdaabstraction.Thosesimplydontwork.hence,$b=(g y)$.$$k1[kk+1a](g y)(f x)k1[kk+1a]gf and k1[kk+1a]yx