# The Semantics of the Lambda Calculus

The theory of the lambda calculus is an equational theory called "lambda-conversion", namely, a set of rules which allows to derive that certain terms are "equal" (i.e. lambda-convertible to each other).

This theory defines a semantics for lambda-terms in the sense that it defines the meaning of a term M as the (equivalence) class of all terms lambda-convertible to M.

It will be useful to introduce some preliminary notions.

#### Free and Bound variables

Given a lambda abstraction \x.M, we say that the operator "\x" is a binder for x, and that the occurrences of x in M are bound. The scope of this binder is the whole term M, except for the subterms of M which contain another binder for x, namely, the subterms which are again of the form \x.N.

These concepts of binder and scope are similar to the concepts of declaration and scope in programming langauges like for instance C, Pascal, or ML.

For example, consider the term

+++ (\x. ... (\x. --- ) *** ) ^^^
The parts ... and *** are in the scope of the outermost \x. The part --- is in the scope of the innermost \x. The parts +++ and ^^^ are out of the scope of both \x.

An occurrence of x is free in M if it is not in the scope of any binder for x.

For example, consider the term

(\x. x y (\x.\y. y z x ) x ) y x
We have 4 occurrences of x, of which only the last is free. The first and the third are bound by the outermost \x and the second is bound by the innermost \x. As for the other variables, we have 3 occurrences of y, of which the first and the last are free, and we have only one occurrence of z, free.

The free variables of M are all the variables which occur free in M. Formally:

FV(x) = {x}
FV(\x.M) = FV(M) - {x}
FV(M N) = FV(M) union FV(N)

#### Substitution

Given a term M, a variable x, and a term N which does not contain any free variable which is bound in M (in a subterm containing x), the term M[N/x] (also denoted by M[x:=N]) is the term obtained from M by replacing every free occurrence of x by N. Formally:
x[N/x] = N
y[N/x] = y
(\y.M)[N/x] = \y.(M[N/x])
(\x.M)[N/x] = \x.M
(M P)[N/x] = (M[N/x])(P[N/x])

The condition "N does not contain free variables which are bound in M" is meant to avoid "variable capture". For example, given M = \y.zx, and N = y, if we simply replaced x by N in M, we would obtain the term \y.zy, which is intuitively incorrect since y, which was free in N, would become bound in M[N/x]. (Or in other words, M was constant on y and would become not constant.)

#### Alpha conversion

The alpha conversion (or alpha renaming) axiom formalizes the idea that "the names of bound variables don't matter". Formally:
\x.M =alpha \y.M[y/x]
provided that y is neither free nor bound in M.

#### Beta conversion

The beta axiom formalizes the notion of transformation which takes place when a function is applied to an argument. Formally:
(\x.M) N =beta M[N/x]
provided that N does not contain free variables which is bound in M (in a subterm containing x), so to avoid variable capture.

Example: (\x. x+1) 5 =beta 5+1 = 6

Variable assumption: To avoid the "variable capture" problem, and more in general, confusion with names, we will assume that all variables that occur free have names different from those of the bound variables, and that all bound variables have different names as well. Note that this assumption is not restrictive since we can always alpha-rename the bound variables.

For example, when we have a term like

x (\x.x(\x.x)x)
x (\y.y(\z.z)y)

Another solution would be to define the notion of substitution so that it renames the variables automatically when needed. For this approach see for instance Hindley and Seldin, Definition 1.1.

#### The theory of the lambda calculus

We will say that M = N is provable in the lambda calculus, or that M and N are lambda-convertible (notation: |- M = N or simply M = N) if M = N can be derived using the alpha axiom, the beta axiom, associativity, reflexivity, transitivity, and the following rules:
• M = N => M P = N P (Congruence 1)
• M = N => P M = P N (Congruence 2)
• M = N => \x.M = \x.N (Xi rule)

# Expressiveness of the Lambda Calculus

We will focus now on the computational power of the Lambda Calculus. We will show that the Lambda Calculus is computationally complete, in the sense that it is able to express all computable functions.

As a definition of computable function, we will use the system of "Recursive Functions" defined by Gödel in 1931.

## Recursive Functions

The recursive functions are defined by using a few basic functions (also called initial functions or elementary functions) and a few rules for defining new functions from the already defined ones.

### Initial functions

• Zero: Z(n) = 0
• Successor: S(n) = n+1
• Projection: Upi(n1,...,np) = ni

### Rules for defining new functions

#### Composition

Given f : Nk -> N and g1,...,gk : Nh -> N, the function f o (g1,...,gk) : Nh -> N (composition of f and g1,...,gk) is the function defined as
(f o (g1,...,gk)) (n1,...,nh) = f(g1(n1,...,nh),..., gk(n1,...,nh))
Example: the function f(n) = n + 2 can be defined as the composition of the successor function with itself, namely f = S o S.

#### Primitive recursion

Given g : Nk -> N and h : Nk+2 -> N, the function f : Nk+1 -> N is defined by primitive recursion from g and h if the following equalities hold:
f(0,n1,...,nk) = g(n1,...,nk)
f(n+1,n1,...,nk) = h(n, f(n,n1,...,nk), n1,...,nk)
Examples:
1. The function plus(n,m) = n + m can be defined by primitive recursion from g = U11 and h = S o U32.
2. The function times(n,m) = n * m can be defined by primitive recursion from g = Z and h = plus o (U33, U32).

#### Minimalization

Given g : Nk+1 -> N, the function f : Nk -> N is defined by minimalization from g if the following holds:
f(n1,...,nk) = mu n. (g(n,n1,...,nk) = 0)
where mu is the minimalization operator: mu n. P(n) returns the least natural number n such that P(n) holds. If such n does not exists, then the result is undefined.

Note that f could be computed by general iteration, i.e. using a while loop of the form

n := 0; while (g(n,n1,...,nk) <> 0) do n := n+1;

Example: Consider the function log2 n = k, where k is the number, if it exists, such that 2k = n (the result is undefined otherwise). Then log2 can be defined by minimalization from the function g(k,n) = | 2k - n |, where | m | represents the absolute value of m.

Definition The set of Recursive Functions is the smallest set which contains the initial functions and is closed w.r.t. composition, primitive recursion, and minimalization.

If we exclude minimalization from this construction, we get the set of Primitive Recursive Fuctions, which are all total. Minimalization is the only operator which introduces non-termination, i.e. partiality.