Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.

Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.

Like this presentation? Why not share!

3,956 views

Published on

No Downloads

Total views

3,956

On SlideShare

0

From Embeds

0

Number of Embeds

1,131

Shares

0

Downloads

163

Comments

0

Likes

21

No embeds

No notes for slide

- 1. Lambda Calculus Dustin Mulcahey
- 2. First, a crash course in mathematical logic...
- 3. First, a crash course in mathematical logic...
- 4. First, a crash course in mathematical logic...
- 5. First, a crash course in mathematical logic...
- 6. For computer scientists, the most interesting part of this discussion is Hilbert’s Entscheidungsproblem.
- 7. For computer scientists, the most interesting part of this discussion is Hilbert’s Entscheidungsproblem.
- 8. For computer scientists, the most interesting part of this discussion is Hilbert’s Entscheidungsproblem. Entscheidungsproblem: Given a mathematical statement, is there an algorithm that will compute a proof or a refutation of that statement?
- 9. For computer scientists, the most interesting part of this discussion is Hilbert’s Entscheidungsproblem. Entscheidungsproblem: Given a mathematical statement, is there an algorithm that will compute a proof or a refutation of that statement? At the time of its statement by Hilbert, there was no formalization of “algorithm”.
- 10. Fast-forward to the late 1920s...
- 11. Fast-forward to the late 1920s... Schoenﬁnkel: “Bound variables are bad. (or, at least, unnecessary)”
- 12. Schoenﬁnkel deﬁned the basic combinators that form the “combinatory logic” (SKI). We’ll deﬁne these in terms of the lambda calculus, once we’ve deﬁned that.
- 13. Schoenﬁnkel deﬁned the basic combinators that form the “combinatory logic” (SKI). We’ll deﬁne these in terms of the lambda calculus, once we’ve deﬁned that. Haskell Curry also formulated the concept of “combinator” in his eﬀorts to unambiguously deﬁne substitution, which had been rather loosely described up until his time (and continues to be loosely described up to this day).
- 14. Schoenﬁnkel also seems to have originated the notion of “currying” (named after Haskell Curry). This is the idea that you can take a two argument function F (x, y ) and express it as a one argument function that is valued in functions: (f (x))(y )
- 15. Finally, on to Alonzo Church! Goal: a new formal system for logic based upon the notion of function application. He wanted something “more natural” than Russell-Whitehead or ZF.
- 16. The formal system that he developed is called the lambda calculus. Here is the identity function expressed in the lambda calculus:
- 17. The formal system that he developed is called the lambda calculus. Here is the identity function expressed in the lambda calculus: λx.x
- 18. Why use λ for function abstraction?
- 19. Why use λ for function abstraction? Whitehead and Russell used x for class abstraction. ˆ If you move the hat oﬀ the x, you get ∧x. Apparently, λx was easier to print than ∧x.
- 20. Why use λ for function abstraction? Whitehead and Russell used x for class abstraction. ˆ If you move the hat oﬀ the x, you get ∧x. Apparently, λx was easier to print than ∧x. At least, that’s how Church told it at one point. Later in life, he claimed that he needed a symbol and he just happened to choose λ.
- 21. In a formal system, we must give clear rules about what sequence of symbols can be produced and how they can be transformed. It’s very similar to designing a programming language.
- 22. To formulate the lambda calculus, we must ﬁrst ﬁx a set of letters that we will use for variables. Typically, we denote these by x, y (we rarely need more than two). Once this has been done, we inductively deﬁne valid lambda terms: If x is a variable, then x is a valid lambda term. If t is a valid lambda term and x is a variable, then (λx.t) is a valid lambda term. (Lambda Abstraction) If t, s are valid lambda terms, then (t s) is a valid lambda term. (Application)
- 23. That’s it! We can now construct all sorts of lambda terms: x (λx.x) y (y y ) ((λx.x)(y y )) (λy .((λx.x)(y y ))) (variable) (lambda abstraction) (variable) (application) (application) (lambda abstraction)
- 24. While I have given the intuition behind the above constructs, they are mere scribblings on paper until we give rules for manipulating the terms. From a proof-theoretic perspective, meaning arises from the reduction rules of the language.
- 25. While I have given the intuition behind the above constructs, they are mere scribblings on paper until we give rules for manipulating the terms. From a proof-theoretic perspective, meaning arises from the reduction rules of the language. This is quite diﬀerent from other notions of meaning, such as Tarski’s deﬁnition of truth or denotionation semantics (in fact, we shall see that denotational semantics turns out to be an interesting problem for the lambda calculus).
- 26. There are three rules for manipulating lambda terms: α-equivalence: renaming variables β-reduction: how function application “works” η-conversion: two functions are “the same” if they do the same thing (extensionality)
- 27. α-equivalence lets us convert λx.x to λy .y .
- 28. α-equivalence lets us convert λx.x to λy .y . Makes sense, right? They are both the identity function. Generally, α-equivalence lets us rename any bound variables.
- 29. As programmers, we use α-equivalence to reason about lexical scoping: x = 0 f = function(x, y) { return x + y; } print f(3,4);
- 30. is equivalent to: x = 0; f = function(a, b) { return a + b; } print f(3,4);
- 31. As you can imagine, formally deﬁning α-equivalence is a bit tricky. We want λx.x α-equivalent to λy .y , but we do not want λx.(λy .x) α-equivalent to λy .(λy .y ).
- 32. As you can imagine, formally deﬁning α-equivalence is a bit tricky. We want λx.x α-equivalent to λy .y , but we do not want λx.(λy .x) α-equivalent to λy .(λy .y ). (The ﬁrst takes a value and produces the constant function at that value, while the second returns the identity function no matter what’s passed to it.)
- 33. β-reduction captures the notion of function application. However, to formally deﬁne it, we run in to the substitution problem again!
- 34. β-reduction captures the notion of function application. However, to formally deﬁne it, we run in to the substitution problem again! Intuitively, we would like (f x) to denote the application of a function f to an input x. Of course, in this world, everything has the same “type”, so we are really applying one lambda term to another.
- 35. For a simple example of β-reduction, let’s apply the identity function to something. ((λx.x)(λy .(y y ))
- 36. For a simple example of β-reduction, let’s apply the identity function to something. ((λx.x)(λy .(y y )) ought to reduce to (λy .(y y ))
- 37. How about the other way around? ((λy .(y y ))(λx.x)
- 38. How about the other way around? ((λy .(y y ))(λx.x) ((λx.x)(λx.x))
- 39. How about the other way around? ((λy .(y y ))(λx.x) ((λx.x)(λx.x)) (λx.x)
- 40. We deﬁne β-reduction as follows. Let ((λx.t) s) be a valid lambda term with t and s lambda terms and x a variable. The above reduces to t[s/x] where t[s/x] denotes the result of replacing every occurrence of x in t by s.
- 41. Problem: what if our usage of variables is a bit too incestuous?
- 42. Problem: what if our usage of variables is a bit too incestuous? Example: t = (λz.(x y )) s =z
- 43. Problem: what if our usage of variables is a bit too incestuous? Example: t = (λz.(x y )) s =z Now apply β-reduction: ((λx.t) s) ((λx.(λz.(x y ))) z) (λz.(z y ))
- 44. Whereas if we ﬁrst did α-equivalence: t = (λw .(x y )) s =z
- 45. Whereas if we ﬁrst did α-equivalence: t = (λw .(x y )) s =z
- 46. Whereas if we ﬁrst did α-equivalence: t = (λw .(x y )) s =z And then apply β-reduction: ((λx.t) s) ((λx.(λw .(x y ))) z) (λw .(z y )) The function on the previous slide applies its parameter to the free variable y , whereas the function on this slide does nothing with its parameter!
- 47. So, obviously some care is needed when deﬁning substitution. We need to ensure that in ((λx.t) s) that s does not contain a free variable that becomes bound when s is substituted for x in t.
- 48. The next and ﬁnal reduction expresses the mathematical principle of extensionality.
- 49. The next and ﬁnal reduction expresses the mathematical principle of extensionality. Informally, we say that two functions are extensionally equal if they do the same thing.
- 50. The next and ﬁnal reduction expresses the mathematical principle of extensionality. Informally, we say that two functions are extensionally equal if they do the same thing. That is, f (x) =x +2 g (x) = x + 1 + 1 are two diﬀerent functions as I have written them, but extensionally equal.
- 51. However (as an aside), 2 −4 f (x) = xx−2 g (x) = x + 2 Are neither equal nor extensionally equal, but algebraically reduce to the same thing.
- 52. η-conversion captures this notion by stating that, for lambda expressions f not containing the variable x, (λx.(f x)) is equivalent to f
- 53. That’s enough math! Let’s do some programming.
- 54. Well, I can do what any beginning (or intermediate, or advanced) programmer does: ((λx.(x x))(λx.(x x)))
- 55. Well, I can do what any beginning (or intermediate, or advanced) programmer does: ((λx.(x x))(λx.(x x))) Let’s apply β-reduction:
- 56. Well, I can do what any beginning (or intermediate, or advanced) programmer does: ((λx.(x x))(λx.(x x))) Let’s apply β-reduction: ((λx.(x x))(λx.(x x))) Yay! An inﬁnite loop! So we see that the true strength of the lambda calculus is the speed at which we can write down inﬁnite computations.
- 57. Or, even better:
- 58. Or, even better: (λx.((x x) x)(λx.((x x) x)
- 59. Or, even better: (λx.((x x) x)(λx.((x x) x) (((λx.((x x) x) (λx.((x x) x)) (λx.((x x) x))
- 60. Or, even better: (λx.((x x) x)(λx.((x x) x) (((λx.((x x) x) (λx.((x x) x)) (λx.((x x) x)) ((((λx.((x x) x) (λx.((x x) x)) (λx.((x x) x)) (λx.((x x
- 61. Or, even better: (λx.((x x) x)(λx.((x x) x) (((λx.((x x) x) (λx.((x x) x)) (λx.((x x) x)) ((((λx.((x x) x) (λx.((x x) x)) (λx.((x x) x)) (λx.((x x . . . This example shows that not all lambda terms normalize. That is, given a lambda term, you can’t always just whack it with β-reduction until it settles into something!
- 62. To make things that are more interesting than non-terminating programs, we need to deﬁne some basic things. I will now deﬁne the following: numbers
- 63. To make things that are more interesting than non-terminating programs, we need to deﬁne some basic things. I will now deﬁne the following: numbers booleans and conditionals
- 64. To make things that are more interesting than non-terminating programs, we need to deﬁne some basic things. I will now deﬁne the following: numbers booleans and conditionals recursion
- 65. The standard formulation of the natural numbers is called the system of Church Numerals.
- 66. The standard formulation of the natural numbers is called the system of Church Numerals. Intuition: The number n is n-fold composition.
- 67. The standard formulation of the natural numbers is called the system of Church Numerals. Intuition: The number n is n-fold composition. (Speaking of non-termination...)
- 68. Less cyclic: The number n is a function that takes a function and returns the nth-fold composite of that function.
- 69. Less cyclic: The number n is a function that takes a function and returns the nth-fold composite of that function. (Hmm, still looks cyclic to me.)
- 70. Less cyclic: The number n is a function that takes a function and returns the nth-fold composite of that function. (Hmm, still looks cyclic to me.) That is, n(f ) = f ◦ f ◦ f ◦ . . . ◦ f
- 71. Less cyclic: The number n is a function that takes a function and returns the nth-fold composite of that function. (Hmm, still looks cyclic to me.) That is, n(f ) = f ◦ f ◦ f ◦ . . . ◦ f which we can denote as f ◦n .
- 72. Formally, 0 ≡ f → id ≡ λf .(λx.x)
- 73. Formally, 0 ≡ f → id 1 ≡f →f ≡ λf .(λx.x) ≡ λf .(λx.(f x))
- 74. Formally, 0 ≡ f → id 1 ≡f →f 2 ≡ ≡ λf .(λx.x) ≡ λf .(λx.(f x))
- 75. Formally, 0 ≡ f → id ≡ λf .(λx.x) 1 ≡f →f ≡ λf .(λx.(f x)) 2 ≡f →f ◦f
- 76. Formally, 0 ≡ f → id ≡ λf .(λx.x) 1 ≡f →f ≡ λf .(λx.(f x)) 2 ≡ f → f ◦ f ≡ λf .(λx.(f (f x))
- 77. Formally, 0 ≡ f → id ≡ λf .(λx.x) 1 ≡f →f ≡ λf .(λx.(f x)) 2 ≡ f → f ◦ f ≡ λf .(λx.(f (f x)) and so on...
- 78. There are two rules for constructing natural numbers:
- 79. There are two rules for constructing natural numbers: 0 ≡ λf .(λx.x)
- 80. There are two rules for constructing natural numbers: 0 ≡ λf .(λx.x) and if n is a natural number, then n+1≡
- 81. There are two rules for constructing natural numbers: 0 ≡ λf .(λx.x) and if n is a natural number, then n + 1 ≡ succ(n) ≡
- 82. There are two rules for constructing natural numbers: 0 ≡ λf .(λx.x) and if n is a natural number, then n + 1 ≡ succ(n) ≡ λf .λx.(f ((n f ) x)
- 83. Is this deﬁnition consistent with what I’ve shown you? 1≡
- 84. Is this deﬁnition consistent with what I’ve shown you? 1 ≡ succ(0)
- 85. Is this deﬁnition consistent with what I’ve shown you? 1 ≡ succ(0) λf .λx.(f ((0 f ) x))
- 86. Is this deﬁnition consistent with what I’ve shown you? 1 ≡ succ(0) λf .λx.(f ((0 f ) x)) λf .λx.(f ((λf .λx.x) f ) x))
- 87. Is this deﬁnition consistent with what I’ve shown you? 1 ≡ succ(0) λf .λx.(f ((0 f ) x)) λf .λx.(f ((λf .λx.x) f ) x)) λf .λx.(f ((λx.x) x))
- 88. Is this deﬁnition consistent with what I’ve shown you? 1 ≡ succ(0) λf .λx.(f λf .λx.(f λf .λx.(f λf .λx.(f ((0 f ) x)) ((λf .λx.x) f ) x)) ((λx.x) x)) x)
- 89. You’ll notice that I’ve suddenly started using the symbol ≡
- 90. You’ll notice that I’ve suddenly started using the symbol ≡ If a ≡ b, I’m declaring by the powers of notation that wherever you write a, you can also write b (and vice versa).
- 91. Also note that succ is itself a lambda term: succ ≡ λn.λf .λx.(f ((n f ) x)) Here, n is not boldface because I’m using it as a variable. The user of our succ function could put anything there! Of course, we only gaurantee good behavior on an input that is equivalent to a natural number (as we have deﬁned them).
- 92. Okay, we have natural numbers. How about addition?
- 93. Okay, we have natural numbers. How about addition? Intuition: n + m takes a function and composes it n + m times.
- 94. Okay, we have natural numbers. How about addition? Intuition: n + m takes a function and composes it n + m times. Strategy: Let’s write a lambda term that applies f m times, “and then”applies it n times.
- 95. Okay, we have natural numbers. How about addition? Intuition: n + m takes a function and composes it n + m times. Strategy: Let’s write a lambda term that applies f m times, “and then”applies it n times. In the world of functions, “and then” means composition! So addition corresponds to composition.
- 96. Okay, we have natural numbers. How about addition? Intuition: n + m takes a function and composes it n + m times. Strategy: Let’s write a lambda term that applies f m times, “and then”applies it n times. In the world of functions, “and then” means composition! So addition corresponds to composition. add ≡ (λn.λm.λf .λx.((n f ) ((m f ) x)))
- 97. Theorem: ((add 2) 2) is equivalent to 4 Proof: (I’m going to use a mixture of deﬁnitional equality and reductions) ((add 2) 2)
- 98. Theorem: ((add 2) 2) is equivalent to 4 Proof: (I’m going to use a mixture of deﬁnitional equality and reductions) ((add 2) 2) (((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2)
- 99. Theorem: ((add 2) 2) is equivalent to 4 Proof: (I’m going to use a mixture of deﬁnitional equality and reductions) ((add 2) 2) (((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2) ((λm.λf .λx.((2 f ) ((m f ) x))) 2)
- 100. Theorem: ((add 2) 2) is equivalent to 4 Proof: (I’m going to use a mixture of deﬁnitional equality and reductions) ((add 2) 2) (((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2) ((λm.λf .λx.((2 f ) ((m f ) x))) 2) (λf .λx.((2 f ) ((2 f ) x))) (λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x)))
- 101. Theorem: ((add 2) 2) is equivalent to 4 Proof: (I’m going to use a mixture of deﬁnitional equality and reductions) ((add 2) 2) (((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2) ((λm.λf .λx.((2 f ) ((m f ) x))) 2) (λf .λx.((2 f ) ((2 f ) x))) (λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x))) (λf .λx.((λx.(f (f x)) (λx.(f (f x)) x)))
- 102. Theorem: ((add 2) 2) is equivalent to 4 Proof: (I’m going to use a mixture of deﬁnitional equality and reductions) ((add 2) 2) (((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2) ((λm.λf .λx.((2 f ) ((m f ) x))) 2) (λf .λx.((2 f ) ((2 f ) x))) (λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x))) (λf .λx.((λx.(f (f x)) (λx.(f (f x)) x))) (λf .λx.((λx.(f (f x)) (f (f x))))
- 103. Theorem: ((add 2) 2) is equivalent to 4 Proof: (I’m going to use a mixture of deﬁnitional equality and reductions) ((add 2) 2) (((λn.λm.λf .λx.((n f ) ((m f ) x))) 2) 2) ((λm.λf .λx.((2 f ) ((m f ) x))) 2) (λf .λx.((2 f ) ((2 f ) x))) (λf .λx.(((λf .λx.(f (f x)) f ) ((λf .(λx.(f (f x)) f ) x))) (λf .λx.((λx.(f (f x)) (λx.(f (f x)) x))) (λf .λx.((λx.(f (f x)) (f (f x)))) (λf .λx.(λf .(f (f (f (f x)))))) 4
- 104. As you can see, doing arithmetic with Church numerals is both simple and fun. What about multiplication?
- 105. Intuition: (n ∗ m) takes a function and returns the n ∗ mth fold composite of the function with itself. Strategy: Make the mth composite of f n times.
- 106. Intuition: (n ∗ m) takes a function and returns the n ∗ mth fold composite of the function with itself. Strategy: Make the mth composite of f n times. mult = λn.λm.λf .λx.((n (m f )) x)
- 107. Theorem: ((mult 2) 2) is equivalent to 4
- 108. Theorem: ((mult 2) 2) is equivalent to 4 Proof: This is left as an exercise for the reader.
- 109. Exponentiation is also straightforward: Strategy: To get mn , apply n to m. Remember that m takes a function and returns the mth fold composite. So now we take the nth fold composite of the function that takes a function and returns the mth fold composite. So now we have a function that takes a function and returns the mn th fold composite.
- 110. Exponentiation is also straightforward: Strategy: To get mn , apply n to m. Remember that m takes a function and returns the mth fold composite. So now we take the nth fold composite of the function that takes a function and returns the mth fold composite. So now we have a function that takes a function and returns the mn th fold composite. Clear, right? How about this:
- 111. Exponentiation is also straightforward: Strategy: To get mn , apply n to m. Remember that m takes a function and returns the mth fold composite. So now we take the nth fold composite of the function that takes a function and returns the mth fold composite. So now we have a function that takes a function and returns the mn th fold composite. Clear, right? How about this: (n m)f = (m ◦ m ◦ · · · ◦ m)f
- 112. Exponentiation is also straightforward: Strategy: To get mn , apply n to m. Remember that m takes a function and returns the mth fold composite. So now we take the nth fold composite of the function that takes a function and returns the mth fold composite. So now we have a function that takes a function and returns the mn th fold composite. Clear, right? How about this: (n m)f = (m ◦ m ◦ · · · ◦ m)f (Remember that composition corresponds to addition.)
- 113. In lambda form: exp ≡ λm.λn.λf λx.(((n m) f ) x)
- 114. Subtraction is much trickier. The most understandable way to do it (that I know of) is to use pairing. Idea: Instead of incrementing x to x + 1, let’s take the pair (n, m) to the pair (m, m + 1). If we start at (0, 0), we’ll get the following sequence:
- 115. Subtraction is much trickier. The most understandable way to do it (that I know of) is to use pairing. Idea: Instead of incrementing x to x + 1, let’s take the pair (n, m) to the pair (m, m + 1). If we start at (0, 0), we’ll get the following sequence: (0, 0) → (0, 1) → (1, 2) → (2, 3) · · ·
- 116. Subtraction is much trickier. The most understandable way to do it (that I know of) is to use pairing. Idea: Instead of incrementing x to x + 1, let’s take the pair (n, m) to the pair (m, m + 1). If we start at (0, 0), we’ll get the following sequence: (0, 0) → (0, 1) → (1, 2) → (2, 3) · · · So, to get the predecessor of n, we just do the above process n times and then take the ﬁrst coordinate of the result. How’s that for eﬃciency?
- 117. Okay, how do we make pairs?
- 118. Okay, how do we make pairs? Well, it will help to ﬁrst deﬁne booleans and conditionals.
- 119. A few deﬁnitions:
- 120. A few deﬁnitions: true ≡ λx.λy .x
- 121. A few deﬁnitions: true ≡ λx.λy .x false ≡ λx.λy .y
- 122. A few deﬁnitions: true ≡ λx.λy .x false ≡ λx.λy .y cond ≡ λc.λt.λf .((c t) f
- 123. A few deﬁnitions: true ≡ λx.λy .x false ≡ λx.λy .y cond ≡ λc.λt.λf .((c t) f
- 124. To make a pair of lambda terms, we will store them both in a cond. To get the ﬁrst, we apply cond to true. To get the second, we apply cond to false.
- 125. To make a pair of lambda terms, we will store them both in a cond. To get the ﬁrst, we apply cond to true. To get the second, we apply cond to false. pair ≡ λf .λs.λc.(((cond c)s)t)
- 126. To make a pair of lambda terms, we will store them both in a cond. To get the ﬁrst, we apply cond to true. To get the second, we apply cond to false. pair ≡ λf .λs.λc.(((cond c)s)t)
- 127. What about my pair increment function? paircrement ≡ λp.((pair (p false))(succ (p true)))
- 128. So, the predecessor function looks like:
- 129. So, the predecessor function looks like: pred ≡ λn.(((n paircrement) ((pair 0) 0) true)
- 130. Also, we can detect when something is zero: isZero ≡ λn.((n(λx. false)) true)
- 131. Phew! We now have conditionals and arithmetic.
- 132. Phew! We now have conditionals and arithmetic. ... and with pairs, we could go ahead and deﬁne the rationals right now. But I’m not going to.
- 133. Phew! We now have conditionals and arithmetic. ... and with pairs, we could go ahead and deﬁne the rationals right now. But I’m not going to. Instead, I want to plunge into recursion!
- 134. Okay, to do recursion, I need a function to call itself.
- 135. Okay, to do recursion, I need a function to call itself. Except in our formal system of lambda calculus, there is no notion of variable binding. All we have are ways of constructing lambda terms and ways of reducing them to other lambda terms.
- 136. Okay, to do recursion, I need a function to call itself. Except in our formal system of lambda calculus, there is no notion of variable binding. All we have are ways of constructing lambda terms and ways of reducing them to other lambda terms. How do we do this?
- 137. Yes, this is where we start talking about the Y combinator.
- 138. Yes, this is where we start talking about the Y combinator. There are a bunch of explanations of this thing, and what follows is one of them.
- 139. Let’s start with a recursive function: fact ≡ λn. ((((cond (isZero n)) 1) ((mult n) (fact (pred n))))
- 140. Let’s start with a recursive function: fact ≡ λn. ((((cond (isZero n)) 1) ((mult n) (fact (pred n)))) This would only make sense if we could make recursive deﬁnitional equalities. But, if you think about it, if we could, then we would just be writing forever...
- 141. Well, we can’t refer to a function by name (except in the very limited sense of ≡). But what if we could pass a function to itself? fact ≡ λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) Well, it wouldn’t make much sense to reduce (fact fact), since we would have to reduce (fact (pred n)), which doesn’t make sense.
- 142. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example):
- 143. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example): ((fact g ) 4)
- 144. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example): ((fact g ) 4) ((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) g ) 4)
- 145. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example): ((fact g ) 4) ((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) g ) 4) λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n)))) 4)
- 146. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example): ((fact g ) 4) ((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) g ) 4) λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n)))) 4) ((((cond (isZero 4)) 1) ((mult n) (g (pred 4))))
- 147. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example): ((fact g ) 4) ((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) g ) 4) λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n)))) 4) ((((cond (isZero 4)) 1) ((mult n) (g (pred 4)))) ((mult n) (g (pred 4)))
- 148. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example): ((fact g ) 4) ((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) g ) 4) λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n)))) 4) ((((cond (isZero 4)) 1) ((mult n) (g (pred 4)))) ((mult n) (g (pred 4))) ((mult n) (g 3))
- 149. But what if we had a magic function g such that g is equivalent to (fact g )? Then, the following would happen (for example): ((fact g ) 4) ((λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) g ) 4) λn. ((((cond (isZero n)) 1) ((mult n) (g (pred n)))) 4) ((((cond (isZero 4)) 1) ((mult n) (g (pred 4)))) ((mult n) (g (pred 4))) ((mult n) (g 3)) ((mult n) ((fact g ) 3))
- 150. Such a magic g is the ﬁxed point of fact.
- 151. Such a magic g is the ﬁxed point of fact. A ﬁxed point of a function f is a value x such that f (x) = x
- 152. Such a magic g is the ﬁxed point of fact. A ﬁxed point of a function f is a value x such that f (x) = x For example: if f (x) = x 2 then 0, 1 are the ﬁxed points of f .
- 153. In the lambda calculus, there is a lambda term that will compute the ﬁxed point of any other lambda term. This is referred to as the Y -combinator. Note that there are several ﬂavors of Y combinator.
- 154. Here’s one: Y = λf .((λx.(f (x x)))(λx.(f (x x))))
- 155. Theorem: for any lambda term h, (Y h) is equivalent to (h (Y h)). Proof:
- 156. Theorem: for any lambda term h, (Y h) is equivalent to (h (Y h)). Proof: (Y h)
- 157. Theorem: for any lambda term h, (Y h) is equivalent to (h (Y h)). Proof: (Y h) (λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h)
- 158. Theorem: for any lambda term h, (Y h) is equivalent to (h (Y h)). Proof: (Y h) (λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h) ((λ x. (h (x x))) (λ x. (h (x x)))
- 159. Theorem: for any lambda term h, (Y h) is equivalent to (h (Y h)). Proof: (Y h) (λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h) ((λ x. (h (x x))) (λ x. (h (x x))) (h ((λ x. (h (x x)) (λ x. (h (x x))))
- 160. Theorem: for any lambda term h, (Y h) is equivalent to (h (Y h)). Proof: (Y h) (λ f. ((λ x. (f (x x))) (λ x. (f (x x)))) h) ((λ x. (h (x x))) (λ x. (h (x x))) (h ((λ x. (h (x x)) (λ x. (h (x x)))) (h (Y h))
- 161. So really, factorial is deﬁned in two steps: fact’ ≡ λf . λn. ((((cond (isZero n)) 1) ((mult n) (f (pred n)))) fact ≡ (Y fact’)
- 162. Which is deﬁnitionally equivalent to this: ((λf . ((λx. (f (x x))) (λx. (f (x x)))) (λf . λn. ((((λc.λt.λf . ((c t) f (λn. ((n (λx. (λx.λy .y ))) (λx.λy .x)) n)) (λf .λx.(fx))) (((λn.λm.λf . (n (m (f )))) n) (f ((λn. (((n (λp. (((λf .λs.λc. ((((λc.λt.λf .((c t) f ) c) s) t)) (p (λx.λy .y ))) ((λf .λx. (f ((n f ) x)) (p (λx.λy .x)))))) (((λf .λs.λc. ((((λc.λt.λf .((c t) f ) c) s) t)) (λf .λx.x)) (λf .λx.x)) (λx.λy .x))) n))))))
- 163. Now that we’ve deﬁned the lambda calculus and written a program in it, I want to discuss some properties of the system as a whole.
- 164. The Church-Turing Thesis Any algorithm that performs a computation can be expressed in the λ-calculus, or by a Turing machine, or by a recursive function (in the sense of recursion theory).
- 165. Undecidability of Equivalence There does not exist an algorithm that decides whether or not two arbitrary lambda terms are equivalent.
- 166. The Church-Rosser Theorem In the λ-calculus, given terms t1 and t2 gotten from a common term t by a sequence of reductions, there exists a term s that t1 and t2 both reduce to.
- 167. The Church-Rosser Theorem In the λ-calculus, given terms t1 and t2 gotten from a common term t by a sequence of reductions, there exists a term s that t1 and t2 both reduce to. t /t /s t2 1
- 168. Equivalence of the λ-calculus and combinatory logic. Deﬁne combinators: I = λx.x K = λx.λy .x S = λx.λy .λz.((x z) (y z)) Then these combinators suﬃce to construct any lambda term, up to equivalence.
- 169. Equivalence of the λ-calculus and combinatory logic. Deﬁne combinators: I = λx.x K = λx.λy .x S = λx.λy .λz.((x z) (y z)) Then these combinators suﬃce to construct any lambda term, up to equivalence. For example, Y = S (K (S I I)) (S (S (K S) K) (K (S I I)))
- 170. Correspondence between SK and propositional logic Consider the axiom of propositional logic: a =⇒ (b =⇒ a)
- 171. Correspondence between SK and propositional logic Consider the axiom of propositional logic: a =⇒ (b =⇒ a) Now look at the K combinator again: λa.λb.a
- 172. Correspondence between SK and propositional logic Consider the axiom of propositional logic: a =⇒ (b =⇒ a) Now look at the K combinator again: λa.λb.a Now repeat this to yourself: “If I have a proof of a, then given a proof of b, I still have a proof of a”
- 173. Now consider the axiom: (a =⇒ (b =⇒ c)) =⇒ ((a =⇒ b) =⇒ (a =⇒ c))
- 174. Now consider the axiom: (a =⇒ (b =⇒ c)) =⇒ ((a =⇒ b) =⇒ (a =⇒ c)) Now look at the S combinator again: λf .λg .λa.((f a)(g a))
- 175. Now consider the axiom: (a =⇒ (b =⇒ c)) =⇒ ((a =⇒ b) =⇒ (a =⇒ c)) Now look at the S combinator again: λf .λg .λa.((f a)(g a)) Now, repeat this to yourself: “If I have a way f of turning proofs of a into proofs that b implies c, then given a proof g that a implies b, I can make a proof that a implies c.”
- 176. Really, the only sane way to think about this stuﬀ is to appeal to category theory.
- 177. Really, the only sane way to think about this stuﬀ is to appeal to category theory. The proposition a =⇒ (b =⇒ a)
- 178. Really, the only sane way to think about this stuﬀ is to appeal to category theory. The proposition a =⇒ (b =⇒ a) Corresponds to an object (“function space”). Think of A as the set of proofs of the proposition a. (AB )A
- 179. Really, the only sane way to think about this stuﬀ is to appeal to category theory. The proposition a =⇒ (b =⇒ a) Corresponds to an object (“function space”). Think of A as the set of proofs of the proposition a. (AB )A Which, in nice categories is isomorphic to A(A×B)
- 180. Really, the only sane way to think about this stuﬀ is to appeal to category theory. The proposition a =⇒ (b =⇒ a) Corresponds to an object (“function space”). Think of A as the set of proofs of the proposition a. (AB )A Which, in nice categories is isomorphic to A(A×B) (All I’ve done here is uncurry.)
- 181. The latter function space contains the ﬁrst projection (which looks an awful lot like K). The existence of this ﬁrst projection shows that the type AA×B is inhabited, and thus the original proposition a =⇒ (b =⇒ a) is valid.
- 182. The correspondence between lambda expression, logical formulas, and objects in categories is called the Curry-Howard-Lambek correspondence.
- 183. Thanks!

No public clipboards found for this slide

Be the first to comment