%%% This is the scribe notes template for CS611
%%% There are several comments preceded by CS611: and boxed in %%%%'s 
%%% which indicate where macros should be altered to set up the header
%%% for the paper.  Your Notes should go at the comment SCRIBE NOTES GO HERE!.

%%% In the various .sty files that accompany this .tex file you will    
%%% find LaTeX macros that make it easier to typeset inference rules    
%%% and programming language constructs.  You must make sure that the   
%%% file proof.sty is in a path searched by LaTeX when you try to       
%%% use this file.  Take a look to see what macros are available--it    
%%% will save you time and make the notes look better.  Feel free to    
%%% extend the set of macros--post them to the newsgroup and contact    
%%% the course staff if you come up with some good ones so they can be  
%%% added to the template.                                              

%%% This template includes examples of how to use some of the macros
%%% to give you an idea of how they work.  (Delete the examples when
%%% you do your scribing.)

\documentclass{article} \usepackage{611-lecture}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: Please fill in these macros as appropriate:
\lecture{3}                  %% Lecture number
\title{$\lambda$ Encodings and Recursion}   %% Title of lecture
\author{Bryant Adams}        %% name of scribe
\date{30 August 2005}     %% Date of lecture, e.g., 1 January 2001
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% See 611.sty for a variety of macros that will be helpful in
% typesetting the lecture. Here are a few of particular interest:
%
% "x"	 	x in keyword font (e.g., "if", "#t")
% _x_	 	x in italics
% \nm{n}   	n in slanted font (used for abbreviations)
% <e> 	 	e in angle brackets
% \lt 	 	less-than sign
% \gt 	 	greater-than sign
% \SB{x}	x in semantic brackets
% \Tr x{y} 	x[[y]] with x in calligraphic font
%          	(if x is more than a single character, use \Tr{x}{y})

\begin{document}

\maketitle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: SCRIBE NOTES GO HERE!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Encoding boolean logic, basic arithmetic, and data structures}

Even though all values in the $\lambda$-calculus are functions, it would 
be nice to somehow have objects which could be worked with like 
constants, such as integers or boolean values. 

\subsection{Encoding booleans}

We wish to implement functions \nm{TRUE}, \nm{FALSE}, \nm{IF}, 
\nm{AND}, and so forth, such that the expected behavior holds, including 
statements such as
\[\begin{array}{rcll}
\nm{IF}~ \nm{TRUE}~ x~ y & \rightarrow & x \\
\nm{AND}~ \nm{TRUE}~ \nm{FALSE} & \rightarrow & \nm{FALSE}
\end{array}\]

If, for no _a priori_ good reason, we define \nm{TRUE} and \nm{FALSE} as:

\[\begin{array}{rcll}
\nm{TRUE} & \definedas \lam{xy}{x}\\
\nm{FALSE} & \definedas \lam{xy}{y}\\
\end{array}\]

Then we see we desire to have \nm{IF} be of the form 
\[\nm{IF}=\lam{b~t~f}{(\textit{if $b=\nm{TRUE}$ then t, if $b=\nm{FALSE}$ 
then f})}\]

And now the definitions used for the boolean values become useful, because 
$\nm{TRUE}~t~f\rightarrow t$ and $\nm{FALSE}~t~f\rightarrow f$, so all we 
need to do is apply the boolean passed to $\nm{IF}$:
\[\nm{IF}\definedas\lam{b~t~f}{(b~t~f)}\]

With \nm{IF} in hand, defining other boolean operators becomes 
straightforward (if rather inefficient):

\[\begin{array}{rcll}
\nm{AND}&\definedas &\lam{b_1~b_2}{\nm{IF}~(b_1)~(\nm{IF}~b_2~\nm{TRUE}~\nm{FALSE})~(\nm{FALSE})}\\
\nm{OR}&\definedas &\lam{b_1~b_2}{\nm{IF}~(b_1)~(\nm{TRUE})~(\nm{IF}~b_2~\nm{TRUE}~\nm{FALSE})}\\
\nm{NOT}&\definedas &\lam{b_1}{\nm{IF}~b_1~\nm{FALSE}~\nm{TRUE}}
\end{array}\]

We have no types here, so while the behavior of these operators is clear 
when they are fed boolean values as we have defined them, they can be 
applied to any $\lambda$-term... though with a good chance of garbage 
coming out.

\subsection{Encoding integers}

To encode numbers, we'll use Church numerals. That is, the number $n$ 
represented as a function which, given another function, returns the $n$-fold composition 
of that other function: $n(f)\mapsto f^n$. So, for example,

\[\begin{array}{rcll}
0& \definedas & \lam{f~x}{x} &\textit{(since $f^0(x)=x$)}\\
1&\definedas & \lam{f~x}{fx} &(f^1=f)\\
2&\definedas & \lam{f~x}{f(fx)} &(f^2(x)=f(f(x)))\\
\nm{SUCC}&\definedas&\lam{n}{\lam{fx}{f((nf)x)}}&\textit{Applying $f$ once 
more}\\
\end{array}\]

With these numbers, we can perform basic arithmetic, such as \nm{PLUS}. An 
obvious approach might be \[\nm{PLUS}\definedas 
\lam{n_1~n_2}{\lam{f~x}{(n_2 f)((n_1 f) x)}}\]
Here we are applying $f^{n_2}$ to $f^{n_1}$ to get $f^{n_1+n_2}$. 
Alternately, recall that numbers (as we have defined them) act on 
functions to repeatedly apply the function, and addition can be viewed as 
repeated application of the successor function:
\[\nm{PLUS}\definedas\lam{n_1~n_2}{(n_1~\nm{SUCC})~n_2}\]

\subsection{Data Structures}
Logic and arithmetic are good places to start, but we still are lacking 
any sort of useful data structure. Consider, for example, ordered pairs. 
It would be nice to have functions \nm{CONS}, \nm{FIRST}, and \nm{SECOND} 
which obeyed the equational specifications:
\begin{eqnarray*} 
\nm{FIRST}(\nm{CONS}(e_1~e_2))&=&e_1\\
\nm{SECOND}(\nm{CONS}(e_1~e_2))&=&e_2\\
\nm{CONS}~(\nm{FIRST}~p)~(\nm{SECOND}~p)&=&p
\end{eqnarray*}
We can begin with \nm{CONS}, trying to wrap two given values for later use 
as the arguments to a yet-unused third value, similar to the manner 
\nm{IF} wrapped its two branch options for extraction by the appropriate 
boolean:
\[\nm{CONS}~\definedas \lam{a~b}{\lam{f}{fab}}\]
To get the first element given to a \nm{CONS}, we need some function which 
will take two arguments and return the first. Conveniently, that is 
exactly what \nm{TRUE} does, as we defined it (note: other encodings of 
booleans are not guaranteed to work!). Similarly, 
$\nm{CONS}~a~b~\nm{FALSE}=b$. Thus, we can define
\begin{eqnarray*}
\nm{FIRST}&\definedas &\lam{p}{p~\nm{TRUE}}\\
\nm{SECOND}&\definedas &\lam{p}{p~\nm{FALSE}}
\end{eqnarray*}
Again, if $p$ isn't a term of the form $\nm{CONS}~a~b$, expect the 
unexpected. 

\section{Recursion and the Y-combinator}

With an encoding for \nm{IF}, we have some control over the flow of a 
program, but we do not yet have the ability to write a loop, such as a 
factorial \nm{FACT} function. In ML, we can write 
\begin{center}
"fun fact(n)=if n$\lt$2 then 1 else n*fact(n-1)"
\end{center}
But how can this be pulled off in the $\lambda$-calculus, where all the 
functions are anonymous? As a first guess, we 
might start with the equational specification 
\[\nm{FACT}=\lam{n}{\nm{IF}(\lt n~2)~(1)~(*~n~(\bigg(\nm{FACT}\bigg)(-~n~1)))}\]
Alas, \nm{FACT} is just shorthand for the stuff on the RHS, and until we know what needs to be 
written down for \nm{FACT}, we can't write down \nm{FACT}. Now if only there were a way to 
remove the recursive 
call...

\subsection{Recursion Removal Trick}
Suppose we break up the recursion into two steps. First, make a function 
\nm{FACT'} which says ``If I was given my own name, I could do what 
\nm{FACT} should''. Thus, if $f=\nm{FACT'}$, then we can treat $\nm{FACT'} 
(f)$ as if it were just \nm{FACT}:

\[\nm{FACT'}~\definedas\lam{f}{\lam{n}{\nm{IF}(\lt n~2)~(1)~(*~n~(\bigg(f~f\bigg)(-~n~1)))}}\]

And, since $\nm{FACT'}~\nm{FACT'}$ should behave as we want $\nm{FACT}$ 
to,
\[\nm{FACT}~\definedas~\nm{FACT'}~\nm{FACT'}\]
We can now see the recursion working:
 \[\begin{array}{rcll} 
\nm{FACT}(4) &=& (\nm{FACT'}~\nm{FACT'})~4\\
&=&\lam{n}{\nm{IF}(\lt n~2)~(1)~(*~n~(\bigg(\nm{FACT'}~\nm{FACT'}\bigg)(-~n~1)))}~(4)\\
&=&\nm{IF}(\lt 4~2)~(1)~(*~4~(\bigg(\nm{FACT}\bigg)(-~4~1)))\\
4*FACT(3)&=&(*~4~(\nm{FACT}(-~4~1)))\\
\end{array}\]
\subsection{Fixed points and the Y-Combinator}
For reasons which will soon become apparent, it might be useful to look at the problem of finding 
\nm{FACT} as a problem of finding a fixed point. Note that for the following function, 
$\nm{FACT}=F(\nm{FACT})=(n~F)(\nm{FACT})$:
\[F=\lam{f}{\lam{n}{\nm{IF}(\lt n~2)~(1)~(*~n~(\bigg(f\bigg)(-~n~1)))}}\]
This comes essentially from wrapping the RHS of the equational specification for $\nm{FACT}$ in 
$\lam{\nm{FACT}}{RHS}$, and could be applied to other recursive functions: that is, every 
recursive function $R$ can be viewed as the fixed point of an associated function $R'$. So, if we 
had a function $Y$ which returns a fixed point of a given input, we could find recursive 
functions $R$ by applying $Y$ to their associated $R'$.

Equationally, we can specify such a $Y$ by \[YF=F(YF)\] This would give us 
\[Y=\lam{F}{\lam{x}{F(YF)x}}\] While this is, itself, recursive, we can apply the recursion 
removal trick to get
 \[\begin{array}{rcll} 
Y&\definedas &Y'~Y'\\
Y'&\definedas&\lam{y}{\lam{F}{\lam{x}{(F((y~y)F))x}}}\\
\end{array}\]

This $Y$ is the infamous ``$Y$-combinator'': A closed $\lambda$-term (combinator) which finds 
solutions to recursion situations. It is more commonly written 
\[Y\definedas\lam{f}{((\lam{x}{fxx})(\lam{x}{fxx}))}\]

Regardless of how it is written, it can be used to define recursive functions without stepping 
through particular cases of recursion removal, such as
\[\nm{FACT}~\definedas~ Y~\lam{f}{(\lam{n}{\nm{IF}(\lt 
n~2)~(1)~(*~n~(f(-~n~1)))})}\]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
