Search code examples
recursionlogiccomputation-theoryhalting-problem

Is it possible to make a halting function if you don't call it on itself?


The standard proof of of the impossibility of solving the halting problem is usually something like this

//does_halt() takes a function as input and returns true if it will ever finish computing

function paradox()
    {if does_halt(paradox())
        {
          while(true){}
        }
    }        

This proof requires that you call the halting function recursively, but is it possible to make a halting function that always computes the correct result as long as it isn't called on itself?


Solution

  • That proof does not require recursion. You are missing the point! You don't call paradox, but pass it like a higher order function. Take this function in Scheme and it's usage:

    ;; does operation passed as x to 2 and 5
    (define (do2by5 x)
      (x 2 5))
    
    ;; examples    
    (do2by5 +)    ; ==> 7
    (do2by5 *)    ; ==> 10
    (do2by5 expt) ; ==> 32
    

    As you see I'm not applying +, * or expt in my examples. I'm just passing it as an argument. It's do2by5 that uses it. In your paradox it seems like you call paradox since you added () to the name. This is wrong since does_halt is supposed to take a function argument just like my do2by5. Here is how I would have written it in Scheme:

    ;; this procedure does not halt!
    (define (forever)
      (forever))
    
    (define (paradox x)
     (if (halt? paradox) ; see I'm not calling it but passing it
         (forever)
         'im-finished))
    

    Now the real juice is of course halt? and it's of course impossible to implement and paradox is the proof you cannot make such a function.

    Halting problem tvivia: What many don't get is that you can actually make halt? for finite sized code living in finite sized memory if the resources you have to investigate it is reasonable larger than the minimum machine that can hold the analyzed program. eg. As an example here is one for all 3 bytes BrainFuck programs reduced to only be Turing complete (eg. without , and .):

    (define (bf3halt? x)
      (not (member x '("+[]" "-[]"))))
    

    For a larger example you can run the program in a virtual environment hashing memory state and program counter. If you ever encounter the same memory and program counter again you have an infinite loop and can return false. (now you see the memory requirements of the halt? can be up to code size of argument times memory consumption of argument when run)