Advanced handouts
Add missing file Co-authored-by: Mark <mark@betalupi.com> Co-committed-by: Mark <mark@betalupi.com>
This commit is contained in:
		
							
								
								
									
										461
									
								
								src/Advanced/Lambda Calculus/parts/00 intro.tex
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										461
									
								
								src/Advanced/Lambda Calculus/parts/00 intro.tex
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,461 @@ | ||||
| \section{Introduction} | ||||
| \textit{Lambda calculus} is a model of computation, much like the Turing machine. | ||||
| As we're about to see, it works in a fundamentally different way, which has a few  | ||||
| practical applications we'll discuss at the end of class. | ||||
|  | ||||
| \vspace{2mm} | ||||
|  | ||||
|  | ||||
| A lambda function starts with a lambda ($\lm$), followed by the names of any inputs used in the expression, | ||||
| followed by the function's output. | ||||
|  | ||||
| For example, $\lm x . x + 3$ is the function $f(x) = x + 3$ written in lambda notation. | ||||
|  | ||||
| \vspace{4mm} | ||||
| Let's disect $\lm x . x + 3$ piece by piece: | ||||
|  | ||||
| \begin{itemize}[itemsep=3mm] | ||||
| 	\item \say{$\lm$} tells us that this is the beginning of an expression. \par | ||||
| 	$\lm$ here doesn't have a special value or definition; \par | ||||
| 	it's just a symbol that tells us \say{this is the start of a function.} | ||||
| 	 | ||||
|  | ||||
| 	\item \say{$\lm x$} says that the variable $x$ is \say{bound} to the function (i.e, it is used for input).\par | ||||
| 	Whenever we see $x$ in the function's output, we'll replace it with the input of the same name. | ||||
|  | ||||
| 	\vspace{1mm} | ||||
|  | ||||
| 	This is a lot like normal function notation: In $f(x) = x + 3$, $(x)$ is \say{bound} | ||||
| 	to $f$, and we replace every $x$ we see with our input when evaluating. | ||||
|  | ||||
|  | ||||
|  | ||||
| 	\item The dot tells us that what follows is the output of this expression. \par | ||||
| 	This is much like $=$ in our usual function notation: \par | ||||
| 	The symbols after $=$ in $f(x) = x + 3$ tell us how to compute the output of this function. | ||||
| \end{itemize} | ||||
|  | ||||
| \problem{} | ||||
| Rewrite the following functions using this notation: | ||||
| \begin{itemize} | ||||
| 	\item $f(x) = 7x + 4$ | ||||
| 	\item $f(x) = x^2 + 2x + 1$ | ||||
| \end{itemize} | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| To evaluate $\lm x . x + 3$, we need to input a value: | ||||
| $$ | ||||
| 	(\lm x . x + 3)~5 | ||||
| $$ | ||||
| This is very similar to the usual way we call functions: we usually write $f(5)$. \par | ||||
| Above, we define our function $f$ \say{in-line} using lambda notation, \par | ||||
| and we omit the parentheses around 5 for the sake of simpler notation. | ||||
|  | ||||
|  | ||||
| \vspace{2mm} | ||||
|  | ||||
|  | ||||
| We evaluate this by removing the \say{$\lm$} prefix and substituting $3$ for $x$ wheverever it appears: | ||||
| $$ | ||||
| (\lm x . \tzm{b}x + 3)~\tzmr{a}5 = | ||||
| 5 + 3 = 8 | ||||
| \begin{tikzpicture}[ | ||||
| 	overlay, | ||||
| 	remember picture, | ||||
| 	out=225, | ||||
| 	in=315, | ||||
| 	distance=0.5cm | ||||
| ] | ||||
| 	\draw[->,gray,shorten >=5pt,shorten <=3pt] | ||||
| 		(a.center) to (b.center); | ||||
| \end{tikzpicture} | ||||
| $$ | ||||
|  | ||||
| \problem{} | ||||
| Evaluate the following: | ||||
| \begin{itemize}[itemsep = 2mm] | ||||
| 	\item $(\lm x. 2x + 1)~4$ | ||||
| 	\item $(\lm x. x^2 + 2x + 1)~3$ | ||||
| 	\item $(\lm x. (\lm y. 9y) x + 3)~2$ \par | ||||
| 	\hint{ | ||||
| 		This function has a function inside, but the evaluation process doesn't change. \\ | ||||
| 		Replace all $x$ with 2 and evaluate again. | ||||
| 	} | ||||
| \end{itemize} | ||||
|  | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| As we saw above, we denote function application by simply putting functions next to their inputs. \par | ||||
| If we want to apply $f$ to $5$, we write \say{$f~5$}, without any parentheses around the function's argument. | ||||
|  | ||||
| \vspace{4mm} | ||||
|  | ||||
| You may have noticed that we've been using arithmetic in the last few problems. | ||||
| This isn't fully correct: addition is not defined in lambda calculus. In fact, nothing is defined: | ||||
| not even numbers! | ||||
|  | ||||
| In lambda calculus, we have only one kind of object: the function. | ||||
| The only action we have is function application, which works by just like the examples above. | ||||
|  | ||||
| \vspace{2mm} | ||||
|  | ||||
| Don't worry if this sounds confusing, we'll see a few examples soon. | ||||
|  | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| \definition{} | ||||
| The first \say{pure} functions we'll define are $I$ and $M$: | ||||
| \begin{itemize} | ||||
| 	\item $I = \lm x . x$ | ||||
| 	\item $M = \lm x . x x$ | ||||
| \end{itemize} | ||||
| Both $I$ and $M$ take one function ($x$) as an input. \par | ||||
| $I$ does nothing, it just returns $x$. \par | ||||
| $M$ is a bit more interesting: it applies the function $x$ on a copy of itself. | ||||
|  | ||||
| \vspace{4mm} | ||||
|  | ||||
| Also, note that $I$ and $M$ don't have a meaning on their own. They are not formal functions. \par | ||||
| Rather, they are abbreviations that say \say{write $\lm x.x$ whenever you see $I$.} | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| \problem{} | ||||
| Reduce the following expressions. \par | ||||
| \hint{ | ||||
| 	Of course, your final result will be a function. \\ | ||||
| 	Functions are the only objects we have! | ||||
| } | ||||
|  | ||||
| \begin{itemize}[itemsep=2mm] | ||||
| 	\item $I~I$ | ||||
| 	\item $M~I$ | ||||
| 	\item $(I~I)~I$ | ||||
| 	\item $\Bigl(~ \lm a .(a~(a~a)) ~\Bigr) ~ I$ | ||||
| 	\item $\Bigl(~(\lm a . (\lm b . a)) ~ M~\Bigr) ~ I$ | ||||
| \end{itemize} | ||||
|  | ||||
| \begin{examplesolution} | ||||
| 	\textbf{Solution for $(I~I)$:}\par | ||||
| 	Recall that $I = \lm x.x$. First, we rewrite the left $I$ to get $(\lm x . x )~I$. \par | ||||
| 	Applying this function by replacing $x$ with $I$, we get $I$: | ||||
| 	$$ | ||||
| 		I ~ I =  | ||||
| 		(\lm x . \tzm{b}x )~\tzm{a}I = | ||||
| 		I | ||||
| 		\begin{tikzpicture}[ | ||||
| 			overlay, | ||||
| 			remember picture, | ||||
| 			out=-90, | ||||
| 			in=-90, | ||||
| 			distance=0.5cm | ||||
| 		] | ||||
| 			\draw[->,gray,shorten >=5pt,shorten <=3pt] | ||||
| 				(a.center) to (b.east); | ||||
| 		\end{tikzpicture} | ||||
| 	$$\null | ||||
| \end{examplesolution} | ||||
|  | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| In lambda calculus, functions are left-associative: \par | ||||
| $(f~g~h)$ means $((f~g)~h)$, not $(f~(g~h))$ | ||||
|  | ||||
| As usual, we use parentheses to group terms if we want to override this order: $(f~(g~h)) \neq ((f~g)~h)$ \par | ||||
| In this handout, all types of parentheses ( $(), [~],$ etc ) are equivalent. | ||||
|  | ||||
| \problem{} | ||||
| Rewrite the following expressions with as few parentheses as possible, without changing their meaning or structure. | ||||
| Remember that lambda calculus is left-associative. | ||||
| \vspace{2mm} | ||||
| \begin{itemize}[itemsep=2mm] | ||||
| 	\item $(\lm x. (\lm y. \lm z. ((xz)(yz))))$ | ||||
| 	\item $((ab)(cd))((ef)(gh))$ | ||||
| 	\item $(\lm x. ((\lm y.(yx))(\lm v.v)z)u) (\lm w.w)$ | ||||
| \end{itemize} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$(\lm x. ((\lm y.(yx))(\lm v.v)z)u) (\lm w.w) \implies (\lm x. (\lm y.yx) (\lm v.v)~z~u) \lm w.w$ | ||||
|  | ||||
| 	\vspace{2mm} | ||||
|  | ||||
| 	It's important that a function's output (everything after the dot) will continue until we hit a close-paren. | ||||
| 	This is why we need the parentheses in the above example. | ||||
| \end{solution} | ||||
|  | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| \definition{Equivalence} | ||||
| We say two functions are \textit{equivalent} if they differ only by the names of their variables: | ||||
| $I = \lm a.a = \lm b.b = \lm \heartsuit . \heartsuit = ...$ \par | ||||
|  | ||||
| \begin{instructornote} | ||||
|  | ||||
| 	The idea behind this is very similar to the idea behind \say{equivalent groups} in group theory: \par | ||||
| 	we do not care which symbols a certain group or function uses, we care about their \textit{structure}. \par | ||||
|  | ||||
| 	\vspace{2mm} | ||||
|  | ||||
| 	If we have two groups with different elements with the same multiplication table, we look at them as identical groups. | ||||
| 	The same is true of lambda functions: two lambda functions with different variable names that behave in the same way are identical. | ||||
|  | ||||
| \end{instructornote} | ||||
|  | ||||
|  | ||||
|  | ||||
| \definition{} | ||||
| Let $K = \lm a. (\lm b . a)$. We'll call $K$ the \say{constant function function.} | ||||
|  | ||||
| \problem{} | ||||
| That's not a typo. Why does this name make sense? \par | ||||
| \hint{What is $K~x$?} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$K x = \lm a . x$, which is a constant function that always outputs $x$. \par | ||||
| 	Given an argument, $K$ returns a constant function with that value.  | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Show that associativity matters by evaluating $\bigl((M~K)~I\bigr)$ and $\bigl(M~(K~I)\bigr)$. \par | ||||
| What would $M~K~I$ reduce to? | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\bigl((M~K)~I\bigr) = (K~K)~I = (\lm a.K)~I = K$ \par | ||||
| 	$\bigl(M~(K~I)\bigr) = M~(\lm a.I) = (\lm a.I)(\lm a.I) = I$ | ||||
| \end{solution} | ||||
|  | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| \generic{Currying:} | ||||
|  | ||||
| In lambda calculus, functions are only allowed to take one argument. \par | ||||
| If we want multivariable functions, we'll have to emulate them through \textit{currying}\footnotemark{}\hspace{-1ex}. | ||||
|  | ||||
| \footnotetext{After Haskell Brooks Curry\footnotemark{}\hspace{-1ex}, a logician that contributed to the theory of functional computation.} | ||||
| \footnotetext{ | ||||
| 	There are three programming languages named after him: Haskell, Brook, and Curry. \par | ||||
| 	Two of these are functional, and one is an oddball GPU language last released in 2007. | ||||
| } | ||||
|  | ||||
| \vspace{1ex} | ||||
|  | ||||
| The idea behind currying is fairly simple: we make functions that return functions. \par | ||||
| We've already seen this on the previous page: $K$ takes an input $x$ and uses it to construct a constant function. | ||||
| You can think of $K$ as a \say{factory} that constructs functions using the input we provide. | ||||
|  | ||||
| \problem{}<firstcardinal> | ||||
| \vspace{1mm} % Slight gap for big paren | ||||
| Let $C = \lm f. \Bigl[\lm g. \Bigl( \lm x. [~ f(g(x)) ~] \Bigr)\Bigr]$. For now, we'll call it the \say{composer.} \par | ||||
| \note[Note]{We could also call $C$ the \say{right-associator.} Why?} | ||||
|  | ||||
| \vspace{3mm} | ||||
|  | ||||
| $C$ has three \say{layers} of curry: it makes a function ($\lm g$) that makes another function ($\lm x$). \par | ||||
| If we look closely, we'll find that $C$ pretends to take three arguments. | ||||
|  | ||||
| \vspace{1mm} | ||||
|  | ||||
| What does $C$ do? Evaluate $(C~a~b~x)$ for arbitrary expressions $a, b,$ and $x$. \par | ||||
| \hint{Evaluate $(C~a)$ first. Remember, function application is left-associative.} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Using the definition of $C$ above, evaluate $C~M~I~\star$ \par | ||||
| Then, evaluate $C~I~M~I$ \par | ||||
| \note[Note]{$\star$ represents an arbitrary expression. Treat it like an unknown variable.} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| As we saw above, currying allows us to create multivariable functions by nesting single-variable functions. | ||||
| You may have notice that curried expressions can get very long. We'll use a bit of shorthand to make them more palatable: | ||||
| If we have an expression with repeated function definitions, we'll combine their arguments under one $\lm$. | ||||
|  | ||||
| \vspace{1ex} | ||||
|  | ||||
| For example, $A = \lm f .[ \lm a . f(f(a))]$ will become $A = \lm fa . f(f(a))$ | ||||
|  | ||||
| \problem{} | ||||
| Rewrite $C = \lm f.\lm g.\lm x. (g(f(x)))$ from \ref{firstcardinal} using this shorthand. | ||||
|  | ||||
| \vspace{25mm} | ||||
|  | ||||
| Remember that this is only notation. \textbf{Curried functions are not multivariable functions, they are simply shorthand!} | ||||
| Any function presented with this notation must still be evaluated one variable at a time, just like an un-curried function. | ||||
| Substituting all curried variables at once will cause errors. | ||||
|  | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| %\iftrue | ||||
| \iffalse | ||||
| 	\generic{$\alpha$-Conversion:} | ||||
| 	There is one more operation we need to discuss. Those of you that have worked with any programming language may | ||||
| 	find that this section sounds like something you've seen before. | ||||
|  | ||||
| 	\vspace{2mm} | ||||
|  | ||||
| 	Variables inside functions are \say{scoped.} We must take care to keep separate variables separate. | ||||
|  | ||||
| 	For example, take the functions \par | ||||
| 	$A = \lm a b . a$ \par | ||||
| 	$B = \lm b . b$ | ||||
|  | ||||
| 	\vspace{2ex} | ||||
|  | ||||
| 	We could say that $(A~B) = \lm b . (\lm b . b)$, and therefore | ||||
| 	$$ | ||||
| 	((A~B)~I) | ||||
| 	= (~ (\lm \tzm{b}b . (\lm b . b))~\tzmr{a}I ~) | ||||
| 	= \lm I . I | ||||
| 	\begin{tikzpicture}[ | ||||
| 		overlay, | ||||
| 		remember picture, | ||||
| 		out=225, | ||||
| 		in=315, | ||||
| 		distance=0.5cm | ||||
| 	] | ||||
| 		\draw[->,gray,shorten >=5pt,shorten <=3pt] | ||||
| 			(a.center) to (b.center); | ||||
| 	\end{tikzpicture} | ||||
| 	$$ | ||||
|  | ||||
| 	Which is, of course, incorrect. $\lm I . I$ is not a valid function. | ||||
| 	This problem arises because both $A$ and $B$ use the input $b$. | ||||
| 	However, each $b$ is \say{bound} to a different function: | ||||
| 	One $b$ is bound to $A$, and the other to $B$. They are therefore distinct. | ||||
|  | ||||
| 	\vspace{2ex} | ||||
|  | ||||
| 	Let's rewrite $B$ as $\lm b_1 . b_1$ and try again: $(A~B) = \lm b . ( \lm b_1 . b_1) = \lm bb_1 . b_1$ \par | ||||
| 	Now, we correctly find that $(A~B~I) = (\lm bc . c)~I = \lm c . c = B = I$. | ||||
| \fi | ||||
|  | ||||
| \problem{} | ||||
| Let $Q = \lm abc.b$. Reduce $(Q~a~c~b)$. \par | ||||
| \hint{ | ||||
| 	You may want to rename a few variables. \\ | ||||
| 	The $a,b,c$ in $Q$ are different than the $a,b,c$ in the expression!	 | ||||
| } | ||||
|  | ||||
| \begin{solution} | ||||
| 	I'll rewrite $(Q~a~c~b)$ as $(Q~a_1~c_1~b_1)$: | ||||
| 	\begin{align*} | ||||
| 		Q = (\lm abc.b) &= (\lm a.\lm b.\lm c.b) \\ | ||||
| 		(\lm a.\lm b.\lm c.b)~a_1 &= (\lm b.\lm c.b) \\ | ||||
| 		(\lm b.\lm c.b)~c_1 &= (\lm c.c_1) \\ | ||||
| 		(\lm c.c_1)~b_1 &= c_1 | ||||
| 	\end{align*} | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Reduce $((\lm a.a)~\lm bc.b)~d~\lm eg.g$ | ||||
|  | ||||
| \begin{solution} | ||||
| 	$((\lm a.a)~\lm bc.b)~d~\lm eg.g$ \\ | ||||
| 	$= (\lm bc.b)~d~\lm eg.g$ \\ | ||||
| 	$= (\lm c.d)~\lm eg.g$ \\ | ||||
| 	$= d$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
							
								
								
									
										42
									
								
								src/Advanced/Lambda Calculus/parts/01 combinators.tex
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								src/Advanced/Lambda Calculus/parts/01 combinators.tex
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,42 @@ | ||||
| \section{Combinators} | ||||
|  | ||||
| \definition{} | ||||
| A \textit{free variable} in a $\lm$-expression is a variable that isn't bound to any input. \par | ||||
| For example, $b$ is a free variable in $(\lm a.a)~b$. | ||||
|  | ||||
| \definition{Combinators} | ||||
| A \textit{combinator} is a lambda expression with no free variables. | ||||
|  | ||||
| \vspace{1mm} | ||||
|  | ||||
| Notable combinators are often named after birds.\hspace{-0.5ex}\footnotemark{} We've already met a few: \par | ||||
| The \textit{Idiot}, $I = \lm a.a$ \par | ||||
| The \textit{Mockingbird}, $M = \lm f.ff$ \par | ||||
| The \textit{Cardinal}, $C = \lm fgx.(~ f(g(x)) ~)$ | ||||
| The \textit{Kestrel}, $K = \lm ab . a$ | ||||
|  | ||||
|  | ||||
|  | ||||
| \problem{} | ||||
| If we give the Kestrel two arguments, it does something interesting: \par | ||||
| It selects the first and rejects the second. \par | ||||
| Convince yourself of this fact by evaluating $(K~\heartsuit~\star)$. | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{}<kitedef> | ||||
| Modify the Kestrel so that it selects its \textbf{second} argument and rejects the first. \par | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\lm ab . b$. | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| We'll call the combinator from \ref{kitedef} the \textit{Kite}, $KI$. \par | ||||
| Show that we can also obtain the kite by evaluating $(K~I)$. | ||||
|  | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
							
								
								
									
										77
									
								
								src/Advanced/Lambda Calculus/parts/02 boolean.tex
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										77
									
								
								src/Advanced/Lambda Calculus/parts/02 boolean.tex
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,77 @@ | ||||
| \section{Boolean Algebra} | ||||
|  | ||||
| The Kestrel selects its first argument, and the Kite selects its second. \par | ||||
| Maybe we can somehow put this \say{choosing} behavior to work... | ||||
|  | ||||
| \vspace{1ex} | ||||
|  | ||||
| Let $T = K\phantom{I} = \lm ab . a$ \par | ||||
| Let $F = KI = \lm ab . b$ | ||||
|  | ||||
| \problem{} | ||||
| Write a function $\text{NOT}$ so that $(\text{NOT} ~ T) = F$ and $(\text{NOT}~F) = T$. \par | ||||
| \hint{What is $(T~\heartsuit~\star)$? How about $(F~\heartsuit~\star)$?} | ||||
|  | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\text{NOT} = \lm a . (a~F~T)$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| How would \say{if} statements work in this model of boolean logic? \par | ||||
| Say we have a boolean $B$ and two expressions $E_T$ and $E_F$. | ||||
| Can we write a function that evaluates to $E_T$ if $B$ is true, and to $E_F$ otherwise? | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
| \problem{} | ||||
| Write functions $\text{AND}$, $\text{OR}$, and $\text{XOR}$ that satisfy the following table. | ||||
|  | ||||
| \begin{center} | ||||
| \begin{tabular}{|| c c || c | c | c ||} | ||||
| 	\hline | ||||
| 	$A$ & $B$ & $(\text{AND}~A~B)$ & $(\text{OR}~A~B)$ & $(\text{XOR}~A~B)$ \\ | ||||
| 	\hline\hline | ||||
| 	F & F & F & F & F \\ | ||||
| 	\hline | ||||
| 	F & T & F & T & T \\ | ||||
| 	\hline | ||||
| 	T & F & F & T & T \\ | ||||
| 	\hline | ||||
| 	T & T & T & T & F \\ | ||||
| 	\hline | ||||
| \end{tabular} | ||||
| \end{center} | ||||
|  | ||||
| \begin{solution} | ||||
| 	There's more than one way to do this, of course. | ||||
| 	\begin{align*} | ||||
| 		\text{AND} &= \lm ab . (a~b~F) = \lm ab . aba \\ | ||||
| 		\text{OR} &= \lm ab . (a~T~b)  = \lm ab . aab \\ | ||||
| 		\text{XOR} &= \lm ab . (a~ (\text{NOT}~b) ~b) | ||||
| 	\end{align*} | ||||
|  | ||||
| 	Another clever solution is $\text{OR} = \lm ab.(M~a~b)$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| To complete our boolean algebra, construct the boolean equality check EQ. \par | ||||
| What inputs should it take? What outputs should it produce? | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\text{EQ} = \lm ab . [a~(bTF)~(bFT)] = \lm ab . [a~b~(\text{NOT}~b)]$ | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	$\text{EQ} = \lm ab . [\text{NOT}~(\text{XOR}~a~b)]$ | ||||
| \end{solution} | ||||
|  | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \pagebreak | ||||
							
								
								
									
										175
									
								
								src/Advanced/Lambda Calculus/parts/03 numbers.tex
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										175
									
								
								src/Advanced/Lambda Calculus/parts/03 numbers.tex
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,175 @@ | ||||
| \section{Numbers} | ||||
|  | ||||
| Since the only objects we have in $\lm$ calculus are functions, it's natural to think of quantities as \textit{adverbs} (once, twice, thrice,...) rather than \textit{nouns} (one, two, three ...)  | ||||
|  | ||||
| \vspace{1ex} | ||||
|  | ||||
| We'll start with zero. If our numbers are \textit{once,} \textit{twice,} and \textit{twice}, it may make sense to make zero \textit{don't}. \par | ||||
| Here's our \textit{don't} function: given a function and an input, don't apply the function to the input. | ||||
| $$ | ||||
| 	0 = \lm fa.a | ||||
| $$ | ||||
| If you look closely, you'll find that $0$ is equivalent to the false function $F$. | ||||
|  | ||||
| \problem{} | ||||
| Write $1$, $2$, and $3$. We will call these \textit{Church numerals}.\hspace{-0.5ex}\footnotemark{} \\ | ||||
| \note{\textit{Note:} This problem read aloud is \say{Define \textit{once}, \textit{twice}, and \textit{thrice}.}} | ||||
|  | ||||
| \footnotetext{after Alonzo Church, the inventor of lambda calculus and these numerals. He was Alan Turing's thesis advisor.} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$1$ calls a function once on its argument: \par | ||||
| 	$1 = \lm fa . (f~a)$. | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	Naturally, \par | ||||
| 	$2 = \lm fa . [~f~(f~a)~]$ \par | ||||
| 	$3 = \lm fa . [~f~(f~(f~a))~]$ | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	The round parentheses are \textit{essential}. Our lambda calculus is left-associative! \par | ||||
| 	Also, note that zero is false and one is the (two-variable) identity. | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| What is $(4~I)~\star$? | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| What is $(3~NOT~T)$? \par | ||||
| How about $(8~NOT~F)$? | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \pagebreak | ||||
|  | ||||
| \problem{} | ||||
| Peano's axioms state that we only need a zero element and a \say{successor} operation to | ||||
| build the natural numbers. We've already defined zero. | ||||
| Now, create a successor operation so that $1 \coloneqq S(0)$, $2 \coloneqq S(1)$, and so on. \par | ||||
| \hint{A good signature for this function is $\lm nfa$, or more clearly $\lm n.\lm fa$. Do you see why?} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$S = \lm n. [\lm fa . f~(n~f~a)] = \lm nfa . [f~(n~f~a)]$ | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	Do $f$ $n$ times, then do $f$ one more time. | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Verify that $S(0) = 1$ and $S(1) = 2$. | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
| Assume that only Church numerals will be passed to the functions in the following problems. \par | ||||
| We make no promises about their output if they're given anything else. | ||||
|  | ||||
| \problem{} | ||||
| Define a function ADD that adds two Church numerals. | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\text{ADD} = \lm mn . (m~S~n) = \lm mn . (n~S~m)$ | ||||
| \end{solution} | ||||
|  | ||||
| \begin{instructornote} | ||||
| 	Defining \say{equivalence} is a bit tricky. The solution above illustrates the problem pretty well. | ||||
|  | ||||
| 	\note{Note: The notions of \say{extensional} and \say{intentional} equivalence may be interesting in this context. Do some reading on your own. | ||||
| 	} | ||||
|  | ||||
| 	\vspace{4ex} | ||||
|  | ||||
| 	These two definitions of ADD are equivalent if we apply them to Church numerals. If we were to apply these two versions of ADD to functions that behave in a different way, we'll most likely get two different results! \\ | ||||
| 	As a simple example, try applying both versions of ADD to the Kestrel and the Kite. | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	To compare functions that aren't $\alpha$-equivalent, we'll need to restrict our domain to functions of a certain form, saying that two functions are equivalent over a certain domain. \\ | ||||
| \end{instructornote} | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Design a function MULT that multiplies two numbers. \par | ||||
| \hint{The easy solution uses ADD, the elegant one doesn't. Find both!} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\text{MULT} = \lm mn . [m~(\text{ADD}~n)~m]$ | ||||
|  | ||||
| 	$\text{MULT} = \lm mnf . [m~(n~f)]$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
| \problem{} | ||||
| Define the functions $Z$ and $NZ$. $Z$ should reduce to $T$ if its input was zero, and $F$ if it wasn't. \par | ||||
| $NZ$ does the opposite. $Z$ and $NZ$ should look fairly similar. | ||||
|  | ||||
| \vspace{1ex} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$Z\phantom{N} = \lm n .[n~(\lm a.F)~T]$ \par | ||||
| 	$NZ = \lm n .[n~(\lm a.T)~F]$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Design an expression PAIR that constructs two-value tuples. \par | ||||
| For example, say $A = \text{PAIR}~1~2$. Then, \par | ||||
| $(A~T)$ should reduce to $1$ and $(A~F)$ should reduce to $2$. | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\text{PAIR} = \lm ab . \lm i . (i~a~b) = \lm abi.iab$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
| From now on, I'll write (PAIR $A$ $B$) as $\langle A,B \rangle$. \par | ||||
| Like currying, this is only notation. The underlying logic remains the same. | ||||
|  | ||||
| \pagebreak | ||||
|  | ||||
| \problem{}<shiftadd> | ||||
| Write a function $H$, which we'll call \say{shift and add.} \par | ||||
| It does exactly what it says on the tin: | ||||
|  | ||||
| \vspace{1ex} | ||||
|  | ||||
| Given an input pair, it should shift its second argument left, then add one. \par | ||||
| $H~\langle 0, 1 \rangle$ should reduce to $\langle 1, 2\rangle$ \par | ||||
| $H~\langle 1, 2 \rangle$ should reduce to $\langle 2, 3\rangle$ \par | ||||
| $H~\langle 10, 4 \rangle$ should reduce to $\langle 4, 5\rangle$ | ||||
|  | ||||
| \begin{solution} | ||||
| 	$H = \lm p . \Bigl\langle~(p~F)~,~S(p~F)~\Bigr\rangle$ | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	Note that $H~\langle 0, 0 \rangle$ reduces to $\langle 0, 1 \rangle$ | ||||
| \end{solution} | ||||
|  | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{}<decrement> | ||||
| Design a function $D$ that un-does $S$. That means \par | ||||
| $D(1) = 0$, $D(2) = 1$, etc. $D(0)$ should be zero. \par | ||||
| \hint{$H$ will help you make an elegant solution.} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$D = \lm n . \Bigl[(~n~H~\langle 0, 0 \rangle~)~T\Bigr]$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
							
								
								
									
										162
									
								
								src/Advanced/Lambda Calculus/parts/04 recursion.tex
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										162
									
								
								src/Advanced/Lambda Calculus/parts/04 recursion.tex
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,162 @@ | ||||
| \section{Recursion} | ||||
|  | ||||
|  | ||||
| %\iftrue | ||||
| \iffalse | ||||
|  | ||||
| 	You now have a choice. Choose wisely --- there's no going back. | ||||
|  | ||||
| 	\begin{tcolorbox}[ | ||||
| 		breakable, | ||||
| 		colback=white, | ||||
| 		colframe=gray, | ||||
| 		arc=0pt, outer arc=0pt | ||||
| 	] | ||||
| 		\raggedright | ||||
| 		\textbf{Take the red pill:} You stay on this page and try to solve \ref{thechallenge}. \par | ||||
| 		This will take a while, and it's very unlikely you'll finish before class ends. | ||||
|  | ||||
|  | ||||
| 		\vspace{4mm} | ||||
|  | ||||
| 		I strongly prefer this option. It's not easy, but you'll be very happy if you solve it yourself. | ||||
| 		This is a chance to build your own solution to a fundamental problem in this field, just as | ||||
| 		Curry, Church, and Turing did when first developing the theory of lambda calculus. | ||||
|  | ||||
| 		- Mark | ||||
| 	\end{tcolorbox} | ||||
|  | ||||
| 	\begin{tcolorbox}[ | ||||
| 		breakable, | ||||
| 		colback=white, | ||||
| 		colframe=gray, | ||||
| 		arc=0pt, outer arc=0pt | ||||
| 	] | ||||
| 		\textbf{Take the blue pill:} You skip this problem and turn the page. | ||||
| 		Half of the answer to \ref{thechallenge} will be free, and the rest will be | ||||
| 		broken into smaller steps. This is how we usually learn out about interesting | ||||
| 		mathematics, both in high school and in university. | ||||
|  | ||||
| 		\vspace{2mm} | ||||
|  | ||||
| 		This path isn't as rewarding as the one above, but it is well-paved | ||||
| 		and easier to traverse. | ||||
| 	\end{tcolorbox} | ||||
|  | ||||
| 	\problem{}<thechallenge> | ||||
| 	Can you find a way to recursively call functions in lambda calculus? \par | ||||
| 	Find a way to define a recursive factorial function. \par | ||||
|  | ||||
| 	\note{$A = (\lm a. A~a)$ doesn't count. You can't use a macro inside itself.} | ||||
|  | ||||
| 	\vfill | ||||
| 	\pagebreak | ||||
| \fi | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| Say we want a function that computes the factorial of a positive integer. Here's one way we could define it: | ||||
| $$ | ||||
| 	x! = \begin{cases} | ||||
| 		x \times (x-1)! & x \neq 0 \\ | ||||
| 		1 & x = 0 | ||||
| 	\end{cases} | ||||
| $$ | ||||
|  | ||||
| We cannot re-create this in lambda calculus, since we aren't given a way to recursively call functions. | ||||
|  | ||||
| \vspace{2mm} | ||||
|  | ||||
| One could think that $A = \lm a. A~a$ is a recursive function. In fact, it is not. \par | ||||
| Remember that such \say{definitions} aren't formal structures in lambda calculus. \par | ||||
| They're just shorthand that simplifies notation. | ||||
|  | ||||
| \begin{instructornote} | ||||
| 	We're talking about recursion, and \textit{computability} isn't far away. At one point or another, it may be good to give the class a precise definition of \say{computable by lambda calculus:} | ||||
|  | ||||
| 	\vspace{4ex} | ||||
|  | ||||
| 	Say we have a device that reduces a $\lm$ expression to $\beta$-normal form. We give it an expression, and the machine simplifies it as much as it can and spits out the result. | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	An algorithm is \say{computable by lambda calculus} if we can encode its input in an expression that resolves to the algorithm's output. | ||||
| \end{instructornote} | ||||
|  | ||||
| \problem{} | ||||
| Write an expression that resolves to itself. \par | ||||
| \hint{Your answer should be quite short.} | ||||
|  | ||||
| \vspace{1ex} | ||||
|  | ||||
| This expression is often called $\Omega$, after the last letter of the Greek alphabet. \par | ||||
| $\Omega$ useless on its own, but it gives us a starting point for recursion. \par | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\Omega = M~M = (\lm x . xx) (\lm x . xx)$ | ||||
|  | ||||
| 	\vspace{1mm} | ||||
| 	 | ||||
| 	An uninspired mathematician might call the Mockingbird $\omega$, \say{little omega}. | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| \definition{} | ||||
| This is the \textit{Y-combinator}. You may notice that it's just $\Omega$ put to work. | ||||
| $$ | ||||
| 	Y = \lm f . (\lm x . f(x~x))(\lm x . f(x~x)) | ||||
| $$ | ||||
|  | ||||
| \problem{} | ||||
| What does this thing do? \par | ||||
| Evaluate $Y f$. | ||||
|  | ||||
|  | ||||
|  | ||||
| %\vfill | ||||
|  | ||||
| %\definition{} | ||||
| %We say $x$ is a \textit{fixed point} of a function $f$ if $f(x) = x$. | ||||
|  | ||||
| %\problem{} | ||||
| %Show that $Y F$ is a fixed point of $F$. | ||||
|  | ||||
| %\vfill | ||||
|  | ||||
| %\problem{} | ||||
| %Let $b = (\lm xy . y(xxy))$ and $B = b ~ b$. \par | ||||
| %Let $N = B F$ for an arbitrary lambda expression $F$. \par | ||||
|  | ||||
| %Show that $F N = N$. | ||||
|  | ||||
| %\vfill | ||||
|  | ||||
| %\problem{Bonus} | ||||
| %Find a fixed-point combinator that isn't $Y$ or $\Theta$. | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
							
								
								
									
										130
									
								
								src/Advanced/Lambda Calculus/parts/05 challenges.tex
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										130
									
								
								src/Advanced/Lambda Calculus/parts/05 challenges.tex
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,130 @@ | ||||
| \section{Challenges} | ||||
|  | ||||
| Do \ref{Yfac} first, then finish the rest in any order. | ||||
|  | ||||
| \problem{}<Yfac> | ||||
| Design a recursive factorial function using $Y$. | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\text{FAC} = \lm yn.[Z~n][1][\text{MULT}~n~(y~(\text{D}~n))]$ | ||||
|  | ||||
| 	To compute the factorial of 5, evaluate $(\text{Y}~\text{FAC}~5)$. | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Design a non-recursive factorial function. \par | ||||
| \note{This one is easier than \ref{Yfac}, but I don't think it will help you solve it.} | ||||
|  | ||||
| \begin{solution} | ||||
| 	$\text{FAC}_0 = \lm p . | ||||
| 	\Bigl\langle~~ | ||||
| 	\Bigl[D~(p~t)\Bigr] | ||||
| 	~,~ | ||||
| 	\Bigl[\text{MULT}~(p~T)~(p~F)\Bigr] | ||||
| 	~~\Bigr\rangle | ||||
| 	$ | ||||
|  | ||||
| 	\vspace{2ex} | ||||
|  | ||||
| 	$ | ||||
| 	\text{FAC} = \lm n . | ||||
| 	\bigl( n~\text{FAC}_0~\langle n, 1 \rangle \bigr) | ||||
| 	$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
|  | ||||
|  | ||||
| \problem{} | ||||
| Solve \ref{decrement} without using $H$. \par | ||||
| In \ref{decrement}, we created the \say{decrement} function. | ||||
|  | ||||
| \begin{solution} | ||||
| 	One solution is below. Can you figure out how it works? \par | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	$ | ||||
| 	D_0 = | ||||
| 	\lm p . \Bigl[p~T\Bigr] | ||||
| 	\Bigl\langle | ||||
| 		F ~,~ p~F | ||||
| 	\Bigr\rangle | ||||
| 	\Bigl\langle | ||||
| 		F | ||||
| 		~,~ | ||||
| 		\bigl\langle | ||||
| 			p~F~T ~,~ ( (p~F~T)~(P~F~F) ) | ||||
| 		\bigr\rangle | ||||
| 	\Bigr\rangle | ||||
| 	$ | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	$ | ||||
| 	D = \lm nfa . | ||||
| 	\Bigl( | ||||
| 		n D_0 \Bigl\langle T, \langle f, a \rangle \Bigr\rangle | ||||
| 	\Bigr)~F~F | ||||
| 	$ | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
|  | ||||
|  | ||||
|  | ||||
| \problem{} | ||||
| Using pairs, make a \say{list} data structure. Define a GET function, so that $\text{GET}~L~n$ reduces to the nth item in the list. | ||||
| $\text{GET}~L~0$ should give the first item in the list, and $\text{GET}~L~1$, the \textit{second}. \par | ||||
| Lists have a defined length, so you should be able to tell when you're on the last element. | ||||
|  | ||||
| \begin{solution} | ||||
| 	One possible implementation is | ||||
| 	$\Bigl\langle | ||||
| 		\langle \text{is last} ~,~ \text{item} \rangle | ||||
| 		~,~ | ||||
| 		\text{next}... | ||||
| 	\Bigr\rangle$, where: | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	\say{is last} is a boolean, true iff this is the last item in the list. \par | ||||
| 	\say{item} is the thing you're storing \par | ||||
| 	\say{next...} is another one of these list fragments. | ||||
|  | ||||
| 	It doesn't matter what \say{next} is in the last list fragment. A dedicated \say{is last} slot allows us to store arbitrary functions in this list. | ||||
|  | ||||
| 	\vspace{1ex} | ||||
|  | ||||
| 	Here, $\text{GET} = \lm nL.[(n~L~F)~T~F$] | ||||
|  | ||||
| 	This will break if $n$ is out of range. | ||||
| \end{solution} | ||||
|  | ||||
| \vfill | ||||
| \pagebreak | ||||
|  | ||||
| \problem{} | ||||
| Write a lambda expression that represents the Fibonacci function: \par | ||||
| $f(0) = 1$, $f(1) = 1$, $f(n + 2) = f(n + 1) + f(n)$. | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Write a lambda expression that evaluates to $T$ if a number $n$ is prime, and to $F$ otherwise. | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{} | ||||
| Write a function MOD so that $(\text{MOD}~a~b)$ reduces to the remainder of $a \div b$. | ||||
|  | ||||
| \vfill | ||||
|  | ||||
| \problem{Bonus} | ||||
| Play with \textit{Lamb}, an automatic lambda expression evaluator. \par | ||||
| \url{https://git.betalupi.com/Mark/lamb} | ||||
|  | ||||
| \pagebreak | ||||
		Reference in New Issue
	
	Block a user