[Programming Languages And Lambda calculi] 4.5 Lambda expression numerical coding

4.5 Numerical coding

In Lambda calculus, there are many methods to encode numerical values, but the most popular method comes from Church, so numerical coding is also called Church number. The idea is that a natural number n is encoded into a function with two parameters, the parameters are f and x, and the function applies f to x n times. Therefore, a function of 0 receives an f and x and returns x (equivalent to applying f 0 times). The function of 1 is applied to f once, and so on.
Insert picture description here

The method add1 needs to receive a representative of the value n and produce a representative of the value n + 1. In other words, it receives a function with two parameters and returns another function with two parameters; the new function will apply its first parameter to the second parameter n + 1 times. In order for the first n to be applied, the new function should use the old n.
Insert picture description here

Similar to the encoding of true and false, numerical encoding is also very simple. In order to add two values ​​n and m, we only need to apply add1 to n a total of m times-and m happens to be a function that receives add1 and applies it m times.
Insert picture description here

The idea of ​​using a value as a function is also very useful for defining iszero. After the function receives a value, it returns true if the value is 0, and other returns false; if this function is applied 0 times less than true, the result is true, otherwise it is false .
Insert picture description here

In order to generalize the function to equal numbers, we need subtraction. Just like we use add1 to implement addition, subtraction can be implemented with sub1. However, although the add1, add and iszero functions are very simple in Church's book coding, sub1 will appear slightly more complicated. sub1 function receives the value as a parameter, and the n-th application, but its function has to return at least the application function once. Of course, the inverse function of any function cannot be used to reverse an application.

The function that implements sub1 is divided into two parts:

  • Pair the given parameter x with true. true indicates that the application of f should be skipped
  • Wrap the given function f to receive the pair value, and apply f when the pair value contains false. Must return a pair value containing false to ensure that f will be applied in the future.

The wrap function wraps the given f:
Insert picture description here

The sub1 function receives a n and returns a new function, the new function receives f and x, wraps f with the wrap function, and encodes x and true, uses n on (wrap f) and ⟨true, x⟩ and extracts The second part of the result-f is applied to x (n-1) times.
Insert picture description here

Reminder about encoding: the encoding of 0 is consistent with the encoding of false. Therefore, no program can distinguish between 0 and false, and the programmer must ensure that true and false are used only in a Boolean context. This is similar to the implementation of 0, false and null pointers in C language using the same bit values.

Exercise 4.6

Prove that add1 1 = n 2

answer

add1 1 = (λn.λf.λx.f (n f x)) (λf.λx.f x)

nβ λf.λx.f ((λf.λx.f x) f x)

nβ λf.λx.f ((λx.f x) x)

nβ λf.λx.f ((λx.f x) x)

nβ λf.λx.f (f x) = 2

Exercise 4.7

Prove that iszero 1 = n false

answer

iszero 1 = λn.n (λx.false) true (λf.λx.f x)

nβ (λf.λx.f x) (λx.false) true

nβ (λx.(λx.false) x) true

nβ (λx.false) true

nβ false

Exercise 4.8

Prove that sub1 1 = n 0

answer

sub1 1 = (λn.λf.λx.snd (n (wrap f) ⟨true, x⟩)) (λf.λx.f x)

nβ λf.λx.snd ((λf.λx.f x) (wrap f) ⟨true, x⟩)

nβ λf.λx.snd (λx.(wrap f) x)⟨true, x⟩)

nβ λf.λx.snd ((wrap f) ⟨true, x⟩)

= λf.λx.snd (((λf.λp.⟨false, if (fst p) (snd p) (f (snd p))⟩) f) ⟨true, x⟩)

nβ λf.λx.snd ((λp.⟨false, if (fst p) (snd p) (f (snd p))⟩) ⟨true, x⟩)

nβ λf.λx.snd (⟨false, if (fst ⟨true, x⟩) (snd ⟨true, x⟩) (f (snd ⟨true, x⟩))⟩)

→→n λf.λx.snd (⟨false, if true (snd ⟨true, x⟩) (f (snd ⟨true, x⟩))⟩

→→n λf.λx.snd (⟨false, snd ⟨true, x⟩)⟩

→→n λf.λx.snd ⟨false, x⟩

→→n λf.λx.x

= 0

Exercise 4.9

Define mult in a way that helps us implement add. In other words, to achieve (mult nm), use the fact that n itself applies the function n times, and apply m to 0 n additions. (Hint: What type of value is (add m)?)

answer

mult ≐ λn.λm.λf.m (n f)

Exercise 4.10

Lambda calculus does not provide an error signal mechanism. What will happen if sub1 is applied to 0? What happens when iszero is applied to true?

answer
  • sub1 0 = (λn.λf.λx.snd (n (wrap f) ⟨true, x⟩)) (λf.λx.x)

    nβ λf.λx.snd ((λf.λx.x) (wrap f) ⟨true, x⟩)

    nβ λf.λx.snd ((λx.x) ⟨true, x⟩)

    nβ λf.λx.snd ⟨true, x⟩

    →→n λf.λx.x = 0

  • iszero true = (λn.n (λx.false) true) (λx.λy.x)

    nβ (λx.λy.x) (λx.false) true

    nβ λy.λx.false true

    nβ λx.false

Guess you like

Origin blog.csdn.net/qq_35714301/article/details/113821416