Relational operations using only increment, loop, assign, zero

后端 未结 1 480
一生所求
一生所求 2021-01-05 14:26

This is a follow up question for: Subtraction operation using only increment, loop, assign, zero

We\'re only allowed to use the following operations:

  1. i
相关标签:
1条回答
  • 2021-01-05 14:42

    The set of natural numbers N is closed under addition and subtraction:

    N + N = N
    N - N = N
    

    This means that the addition or subtraction of two natural numbers is also a natural number (considering 0 - 1 is 0 and not -1, we can't have negative natural numbers).

    However, the set of natural numbers N is not closed under relational operations:

    N < N = {0, 1}
    N > N = {0, 1}
    

    This means that the result of comparing two natural numbers is either truthfulness (i.e. 1) or falsehood (i.e. 0).

    So, we treat the set of booleans (i.e. {0, 1}) as a restricted set of the natural numbers (i.e. N).

    false = 0
    true  = incr(false)
    

    The first question we must answer is “how do we encode if statements so that we may branch based on either truthfulness or falsehood?” The answer is simple, we use the loop operation:

    isZero(x) {
        y = true
        loop x { y = false }
        return y
    }
    

    If the loop condition is true (i.e. 1) then the loop executes exactly once. If the loop condition is false (i.e. 0) then the loop doesn't execute. We can use this to write branching code.

    So, how do we define the relational operations? Turns out, everything can be defined in terms of lte:

    lte(x, y) {
        z = sub(x, y)
        z = isZero(z)
        return z
    }
    

    We know that x ≥ y is the same as y ≤ x. Therefore:

    gte(x, y) {
        z = lte(y, x)
        return z
    }
    

    We know that if x > y is true then x ≤ y is false. Therefore:

    gt(x, y) {
        z = lte(x, y)
        z = not(z)
        return z
    }
    

    We know that x < y is the same as y > x. Therefore:

    lt(x, y) {
        z = gt(y, x)
        return z
    }
    

    We know that if x ≤ y and y ≤ x then x = y. Therefore:

    eq(x, y) {
        l = lte(x, y)
        r = lte(y, x)
        z = and(l, r)
        return z
    }
    

    Finally, we know that if x = y is true then x ≠ y is false. Therefore:

    ne(x, y) {
        z = eq(x, y)
        z = not(z)
        return z
    }
    

    Now, all we need to do is define the following functions:

    1. The sub function is defined as follows:

      sub(x, y) {
          loop y
              { x = decr(x) }
          return x
      }
      
      decr(x) {
          y = 0
          z = 0
      
          loop x {
              y = z
              z = incr(z)
          }
      
          return y
      }
      
    2. The not function is the same as the isZero function:

      not(x) {
          y = isZero(x)
          return y
      }
      
    3. The and function is the same as the mul function:

      and(x, y) {
          z = mul(x, y)
          return z
      }
      
      mul(x, y) {
          z = 0
          loop x { z = add(y, z) }
          return z
      }
      
      add(x, y) {
          loop x
              { y = incr(y) }
          return y
      }
      

    That's all you need. Hope that helps.

    0 讨论(0)
提交回复
热议问题