; Operations with Church Numerals ; ------------------------------- ; We already saw how to get the number that follows a given number. Now ; how to do addition, subtraction, multiplication, etc. ; Addition: ; We can repeat succ on m for n times in order to add n to m: (define add (lambda (n) (lambda (m) ((n succ) m) ) ) ) ; We can evaluate it into: (define add (lambda (m) (lambda (n) (lambda (f) (lambda (x) ((m f) ((n f) x) ) ) ) ) ) ) ; Now let's try multiplication. Since a church numeral is basically about ; repeating something n times, we can repeat the other multiplicand N times. (define mult (lambda (m) (lambda (n) (lambda (f) (m (n f)) ) ) ) ) ; Power: we can repeat the LC's mult m times (define power (lambda (m) (lambda (n) ((n (mult m)) (succ zero)) ) ) ) ; This, in turn can be simplified into: (define power (lambda (m) (lambda (n) (n m) ) ) ) (display (church->int ((power zero) zero))) ; Displays 1, which is another proof that 0^0 is 1. ; Predecessor ; ----------- ; Getting the predecessor in Church numerals is quite tricky. ; Let's consider the following method: ; ; Create a pair [0,0] and convert it into the pair [0,1]. (what ; we do is take the cdr and put it in the car and set the cdr to it plus ; 1). ; ; Then into [1,2], [2,3], etc. Repeat this process N times and ; we'll get [N-1, N]. ; ; Then we can return the first element of the final pair which is N-1. (define pred_next_tuple (lambda (tuple) ((lc_cons (lc_cdr tuple)) (succ (lc_cdr tuple))) ) ) ; Note that we base the next tuple on the second item of the original tuple. (define pred (lambda (n) (lc_car ((n pred_next_tuple) ; A tuple with two zeros. ((lc_cons zero) zero) ) ) ) ) ; Note that the pred of zero is zero, because there isn't -1 in church numerals ; Subtraction is simply repeating pred m times (define subtract (lambda (n) (lambda (m) ((m pred) n) ) ) ) ; Now, how do we compare two Church numerals? We can subtract the ; first one from the second one. If the result is equal to zero, then the ; second one is greater or equal to the first. (define is-zero? (lambda (n) ((n (lambda (x) lc_false)) lc_true) ) ) (define less-or-equal (lambda (x) (lambda (y) (is-zero? ((subtract x) y)) ) ) ) ; In a similar way and by using not we can define all other comparison ; operators. ; Division and modulo? For this we need the Y combinator. ; Stay tuned...