Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtraction operation using only increment, loop, assign, zero

I am trying to build up subtraction, addition, division, multiplication and other operations using only following ones:

  1. incr(x) - Once this function is called it will assign x + 1 to x
  2. assign(x, y) - This function will assign the value of y to x (x = y)
  3. zero(x) - This function will assign 0 to x (x = 0)
  4. loop X { } - operations written within brackets will be executed X times

Using following rules it is straight forward to implement addition (add) like this:

ADD (x, y) {
 loop X {
   y = incr (y)
 }
return y
}

However, I'm struggling to implement subtraction. I think that all the other needed operations could be completed using subtraction.

Any hint will be very appreciated.

like image 923
fiz Avatar asked Dec 03 '15 23:12

fiz


1 Answers

Stephen Cole Kleene devised a way to perform integer subtraction using integer addition. However, it assumes that you cannot have negative integers. For example:

0 - 1 = 0
1 - 1 = 0
2 - 1 = 1
3 - 1 = 2
4 - 1 = 3
5 - 2 = 3
6 - 3 = 3
6 - 4 = 2
6 - 5 = 1
6 - 6 = 0
6 - 7 = 0

In your question, you implemented the addition operation using the increment operation.

Similarly, you can implement the subtraction operation using the decrement operation as follows:

sub(x, y) {
    loop y
        { x = decr(x) }
    return x
}

Now, all we need to do is implement the decrement operation.

This is where the genuis of Kleene shines:

decr(x) {
    y = 0
    z = 0

    loop x {
        y = z
        z = incr(z)
    }

    return y
}

Here we've used all the four operations. This is how it works:

  1. We have two base cases, y (the base case for 0) and z (the base case for 1):

    y = 0 - 1 = 0
    z = 1 - 1 = 0
    

    Hence, we initialize them both to 0.

  2. When x is 0 we run the loop 0 times (i.e. never) and then we simply return y = 0.

  3. When x is 1 then we run the loop once, assign y = z and then simply return y = z = 0.

Notice that every time we run the loop y holds the result of the current iteration while z holds the result of the next iteration. This is the reason why we require two base cases. The decrement function is not a continuous function. It is a piecewise function:

decr(0)     = 0
decr(n + 1) = n

Kleene realized this when he went to the dentist and the dentist extracted two of his teeth. He was frustrated while trying to solve this very problem and when the dentist extracted two of his teeth he realized that he required two base cases.

like image 152
Aadit M Shah Avatar answered Sep 21 '22 22:09

Aadit M Shah