We don't need to worry about the case illustrated in the second figure, because it is converted into the case handled by Proposition LC2 by -conversion. The only case left to us to consider is that in which the inner redux occurs in the argument of the outer redux.
Recall the diagram of this case. If we perform the outer reduction before the inner one (the "call-by-name" case), we get a copy of the inner redux for every occurrence of the variable of the outer -bound variable in the body of the outer -abstraction.
If, on the other hand (the "call-by-value" case), we perform the inner reduction before the outer one, we get exactly one contractum of the inner redex, leaving us with a new version of the outer redex with that contractum in place of the inner redex.
Obviously, to achieve local confluence, we have to reduce those redexes (under discussion) which remain unreduced in each case. In the call-by-value case, the outer redex will be reduced, resulting in the substitution of the inner contractum for all occurrences of the variable of the lambda-abstraction of the outer redex in the body of that abstraction.
However, in the call-by-name case, the inner-redex has been copied zero or more times in the body of the lambda-abstraction of the outer redex. In order to bring this "call-by-name" reduction into line with the "call-by-value" case, we will have to reduce every one of the copies of the inner-redex. This means that we will need to show that the final substitution which occurs in the call-by-value case gives an identical result to multiple-constructive-updates along paths which are the effect of multiple applications of our function.
The practical result of this is that, since (in the call-by-value case) we have to separately reduce each copy of the inner-redux, we will use a distinct path to address each redux. We can characterise multiple -reductions by a sequence of paths, each of which addresses one redux-copy.
How are we to create this path-sequence? Well, let's observe that each copy of the inner-redux occurs in place of an ocurrence of the outer lambda-bound variable in the original outer-redux. Thus, if we can make a list of all paths to occurrences of a specified variable in an expression, we will be well placed to being able to use such a list (or finite sequence) as a way of specifying the -reductions required to bring the call-by-name form in line with the call-by-value one. This is achieved by the paths function, defined below.
However we have to show identity (up to -conversion) of substitution with multiple conversions along paths. This is achieved primarily by Lemma PT4 which shows that the substitution E[v:=F] can be accomplished by a series of updates of paths leading to v in E
However, before we can begin work upon this key lemma, we need to refresh our memory about various general functions defined on finite sequences which are familiar to users of functional languages, to whit map and reduce.
The reduce function (not to be confused with the term reduction as we have been using it) takes a binary operation as argument, and in essence uses that binary operation to combine elements of a finite sequence together. A second argument is supplied to provide a base for the combination. It helps us (or at least it helped me) to visualise what's going on if we write the binary operation infixed as o. Thus, if P is a sequence, then
It is essential to remember the right-associativity when we come to use reduce for real later.
An elementary example of the use of reduce is.
RED1 reduce(o, y, ()) = y
RED2 reduce(o, y, x::s) = x o reduce(o, y, s)
The reduce function as defined above is missing the first argument that the reduce function has in the 287 course.
MAP1 map(f, ()) = ()
MAP2 map(f, x::s) = f(x) :: map(f,s)
CC1 () <> s = s
CC2 (x::s) <> t = x::(s<>t)
EXT1 ext(s)(p)=s::p
PL1 paths(v,v) = ((v))
PL2 paths(u,v) = (())
PL3 paths(c,v) = (())
PL4 paths((F G),v) = map(ext(0),paths(F,v)) <> map(ext(1),paths(G,v))
PL5 paths(( v. H),v) = ()
PL6 paths(( u. H),v) = map(ext(1), paths(H,v))
Now the above definition of paths makes use of the concatenation operator "<>", as well as the map function. Our general strategy will be to use the reduce function to combine the effects of multiple -reductions. Thus inevitably reduce is going to interact with "<>" and with map. Let's prove a couple of lemmas that address that interaction.
The following lemma is fairly obvious if we think about reduce in the right way. Suppose, for example, we have two path-sequences P and P'. Then
On the one hand, from the definition of "<>".
reduce(o, b, l1 <> l2) = reduce(o, b, l2)
= reduce(o,b,l2)
Hence the result holds in the base case.
we have to show that the result holds for a sequence s::l where length(l) = n. Applying first the definition of "<>" and then the definition of reduce we obtain
= s o reduce(o,reduce(o,b,l2),l)
Hence the result holds for any sequence s::l of length n+1. Hence the result holds for all finite sequences.
Next we come to the interaction of reduce and the use of map in the definition of paths. In this case, we prove lemmas specific to the actual use of map in the definition of paths. These lemmas are motivated by the requirements of Lemma PT4, which shows how substitution can be performed using path-updates - so those seeking motivation of the immediate lemmas should perhaps look first at PT4.
reduce(o,(G H), map(ext(1),p::P))
=reduce(o,(G H), (1::p) :: map(ext(1),P))
= (1::p) o reduce(o,(G H), (1::p) :: map(ext(1),P))
(1::p) o (G reduce(o,H,P))
= (G reduce(o,H,P))[(1::p) := F]
= (G reduce(o,H,P)[p := F])
= (G p o reduce(o,H,P))
= (G reduce(o,H,p::P))
and, from the definition of reduce
Hence using Lemma Red1 we obtain
RHS = reduce(o,E,paths(E,v))
= reduce(o, E, map(ext(0),paths(G,v)) <> map(ext(1),paths(H,v)))
= reduce(o, reduce(o, E, map(ext(1),paths(H,v)), map(ext(0),paths(G,v))
Now consider the inner reduce term. We apply Lemma Red2 to this.
RHS = reduce(o, (G H[v:=F]) map(ext(0),paths(G,v)))
which by a similar use of Lemma Red2 is seen to be
So the lemma holds in this case (Phew! - and there's more to come).
E[v:=F] = E
Concluding this case.
Now, because no variable free in F is bound in E
RHS = reduce(o,E,paths(E,v))
= reduce(o, E, map(ext(1),paths(H,v)))
= u.(reduce o, H, paths(H,v))
by Red4. And, from the inductive hypothesis we have
= u.H[v:=F])