Content uploaded by PL Olcott

Author content

All content in this area was uploaded by PL Olcott on Sep 26, 2021

Content may be subject to copyright.

Halting problem undecidability and infinitely nested simulation

The halting theorem counter-examples present infinitely nested simulation (non-halting)

behavior to every simulating halt decider. The pathological self-reference of the conventional

halting problem proof counter-examples is overcome. The halt status of these examples is

correctly determined. A simulating halt decider remains in pure simulation mode until after it

determines that its input will never reach its final state. This eliminates the conventional

feedback loop where the behavior of the halt decider effects the behavior of its input.

The x86utm operating system was created so that the halting problem could be examined

concretely in the high level language of C. H is a function written in C that analyzes the x86

machine language execution trace of other functions written in C. H recognizes simple cases

of infinite recursion and infinite loops. The conventional halting problem proof counter-

example template is shown to simply be an input that does not halt.

H simulates its input with an x86 emulator until it determines that its input would never halt.

As soon as H recognizes that its input would never halt it stops simulating this input and

returns 0. For inputs that do halt H acts exactly as if it was an x86 emulator and simply runs

its input to completion and then returns 1.

In theoretical computer science the random-access stored-program (RASP)

machine model is an abstract machine used for the purposes of algorithm

development and algorithm complexity theory. ...The RASP is closest of all

the abstract models to the common notion of computer.

https://en.wikipedia.org/wiki/Random-access_stored-program_machine

The C/x86 model of computation is known to be Turing equivalent on the basis that it maps

to the RASP model for all computations having all of the memory that they need. As long as

an C/x86 function is a pure function of its inputs the C/x86 model of computation can be

relied upon as a much higher level of abstraction of the behavior of actual Turing machines.

This criteria merely relies on the fact that the UTM simulation of a machine description of a

machine is computationally equivalent to the direct execution of this same machine:

Simulating Halt Decider Theorem (Olcott 2020):

A simulating halt decider correctly decides that any input that never halts unless the

simulating halt decider aborts its simulation of this input is an input that never halts.

the Turing machine halting problem. Simply stated, the problem is: given

the description of a Turing machine M and an input w, does M, when started

in the initial configuration q0w, perform a computation that eventually halts?

(Linz:1990:317).

In computability theory, the halting problem is the problem of determining,

from a description of an arbitrary computer program and an input, whether

the program will finish running, or continue to run forever.

https://en.wikipedia.org/wiki/Halting_problem

---1--- 2021-09-26 09:39 AM

The halting problem is always about program descriptions not running programs. This

means that it is always about the input to the halt decider not the direct execution of the

program. If the input to the simulating halt decider never halts unless the halt decider aborts

its simulation of this input then its input never halts.

Because H only acts as a pure simulator of its input until after its halt status decision has

been made it has no behavior that can possibly effect the behavior of its input. Because of

this H screens out its own address range in every execution trace that it examines. This is

why we never see any instructions of H in any execution trace after an input calls H.

Pathological Input to a halt decider is stipulated to mean any input that was defined to do

the opposite of whatever its corresponding halt decider decides as Sipser describes:

Now we construct a new Turing machine D with H as a subroutine.

This new TM calls H to determine what M does when the input to M

is its own description ⟨M⟩. Once D has determined this information,

it does the opposite. (Sipser:1997:165)

When D is invoked with input ⟨D⟩ we have pathological self-reference when D calls H with ⟨D⟩

and does the opposite of whatever H returns.

Does D halt on its own machine description ⟨D⟩ ?

This question can only be correctly answered after the pathology has been removed. When

a halt decider only acts as a pure simulator of its input until after its halt status decision is

made there is no feedback loop of back channel communication between the halt decider

and its input that can prevent a correct halt status decision. In this case the halt decider is

only examining the behavior of the input. It ignores it own behavior.

The standard pseudo-code halting problem template "proved" that the halting problem could

never be solved on the basis that neither value of true (halting) nor false (not halting) could

be correctly returned form the halt decider to the confounding input.

procedure compute_g(i): // (Wikipedia:Halting Problem)

if f(i, i) == 0 then // adapted from (Strachey, C 1965)

return 0 // originally written in CPL

else // ancestor of the BCPL, B and C

loop forever // programming languages

This problem is overcome on the basis that a simulating halt decider would abort the

simulation of its input before ever returning any value to this input. It aborts the simulation of

its input on the basis that its input specifies what is essentially infinite recursion (infinitely

nested simulation) to any simulating halt decider.

Every input to a simulating halt decider that only stops running when its simulation is aborted

unequivocally specifies a computation that never halts. When input to a simulating halt

decider cannot possibly reach its final state then we know that this input never halts.

---2--- 2021-09-26 09:39 AM

A simulating halt decider H divides all of its input into:

(1) Those inputs that never halt unless H aborts their simulation (never halting).

H aborts its simulation of these inputs an returns 0 for never halting.

(2) Those inputs that halt while H remains a pure simulator (halting).

H waits for its simulation of this input to complete and then returns 1 halting.

H derives the execution trace of its inputs as a pure function of these inputs.

H derives its halt status decision as a pure function of this derived execution trace.

Therefore H derives its halt status decision as a pure function of its inputs.

---3--- 2021-09-26 09:39 AM

Simulating partial halt decider H correctly decides that P(P) never halts (V1)

H analyzes the (currently updated) stored execution trace of its x86 emulation of P(P) after it

simulates each instruction of input (P, P). As soon as a non-halting behavior pattern is

matched H aborts the simulation of its input and decides that its input never halts.

The execution trace of the x86 emulation of P(P) by simulating halt decider H conclusively

proves that P never halts unless H aborts its simulation of P. This provides complete proof

that that the input to H never halts thus H(P,P)==0 is correct.

// Simplified Linz Ĥ (Linz:1990:319)

// Strachey(1965) CPL translated to C

void P(u32 x)

{

if (H(x, x))

HERE: goto HERE;

}

int main()

{

Output("Input_Halts = ", H((u32)P, (u32)P));

}

_P()

[00000c36](01) 55 push ebp

[00000c37](02) 8bec mov ebp,esp

[00000c39](03) 8b4508 mov eax,[ebp+08] // 2nd Param

[00000c3c](01) 50 push eax

[00000c3d](03) 8b4d08 mov ecx,[ebp+08] // 1st Param

[00000c40](01) 51 push ecx

[00000c41](05) e820fdffff call 00000966 // call H

[00000c46](03) 83c408 add esp,+08

[00000c49](02) 85c0 test eax,eax

[00000c4b](02) 7402 jz 00000c4f

[00000c4d](02) ebfe jmp 00000c4d

[00000c4f](01) 5d pop ebp

[00000c50](01) c3 ret

Size in bytes:(0027) [00000c50]

_main()

[00000c56](01) 55 push ebp

[00000c57](02) 8bec mov ebp,esp

[00000c59](05) 68360c0000 push 00000c36 // push P

[00000c5e](05) 68360c0000 push 00000c36 // push P

[00000c63](05) e8fefcffff call 00000966 // call H(P,P)

[00000c68](03) 83c408 add esp,+08

[00000c6b](01) 50 push eax

[00000c6c](05) 6857030000 push 00000357

[00000c71](05) e810f7ffff call 00000386

[00000c76](03) 83c408 add esp,+08

[00000c79](02) 33c0 xor eax,eax

[00000c7b](01) 5d pop ebp

[00000c7c](01) c3 ret

Size in bytes:(0039) [00000c7c]

machine stack stack machine assembly

address address data code language

======== ======== ======== ========= =============

[00000c56][0010172a][00000000] 55 push ebp

[00000c57][0010172a][00000000] 8bec mov ebp,esp

[00000c59][00101726][00000c36] 68360c0000 push 00000c36 // push P

[00000c5e][00101722][00000c36] 68360c0000 push 00000c36 // push P

[00000c63][0010171e][00000c68] e8fefcffff call 00000966 // call H(P,P)

---4--- 2021-09-26 09:39 AM

Begin Local Halt Decider Simulation at Machine Address:c36

[00000c36][002117ca][002117ce] 55 push ebp

[00000c37][002117ca][002117ce] 8bec mov ebp,esp

[00000c39][002117ca][002117ce] 8b4508 mov eax,[ebp+08]

[00000c3c][002117c6][00000c36] 50 push eax // push P

[00000c3d][002117c6][00000c36] 8b4d08 mov ecx,[ebp+08]

[00000c40][002117c2][00000c36] 51 push ecx // push P

[00000c41][002117be][00000c46] e820fdffff call 00000966 // call H(P,P)

[00000c36][0025c1f2][0025c1f6] 55 push ebp

[00000c37][0025c1f2][0025c1f6] 8bec mov ebp,esp

[00000c39][0025c1f2][0025c1f6] 8b4508 mov eax,[ebp+08]

[00000c3c][0025c1ee][00000c36] 50 push eax // push P

[00000c3d][0025c1ee][00000c36] 8b4d08 mov ecx,[ebp+08]

[00000c40][0025c1ea][00000c36] 51 push ecx // push P

[00000c41][0025c1e6][00000c46] e820fdffff call 00000966 // call H(P,P)

Local Halt Decider: Infinite Recursion Detected Simulation Stopped

We do not see any of the x86 instructions of H in the above execution trace because we

know that H is only acting as a pure simulator of its inputs until after it has made its halt

status decision. This means that H cannot possibly have any effect on the behavior of its

input during the above (execution trace / halt status analysis), thus H can safely ignore its

own instructions in this halt status analysis.

It required that we make sure to ignore the behavior of H in the execution trace so that we

eliminate the pathological self-reference error from the halt status analysis.

We can verify that the above execution trace of the simulation of P(P) is accurate on the

basis that it precisely corresponds to the x86 assembly language source-code of P.

This infinite recursion detection criteria are met by the above execution trace:

(a) P calls H twice in sequence from the same machine address.

(b) With the same parameters: (P,P) to H.

(c) With no conditional branch or indexed jump instructions in the execution trace of P.

(d) We know that there are no return instructions in H because we know that H is in pure

simulation mode.

This conclusively proves that P never halts unless H aborts its simulation of P which proves

that the behavior of the simulation of P on input P by H meets the following criteria:

Simulating Halt Decider Theorem (Olcott 2020):

A simulating halt decider correctly decides that any input that never halts unless the

simulating halt decider aborts its simulation of this input is an input that never halts.

This criteria merely relies on the fact that the UTM simulation of a machine description of a

machine is computationally equivalent to the direct execution of this same machine:

[00000c68][0010172a][00000000] 83c408 add esp,+08

[00000c6b][00101726][00000000] 50 push eax

[00000c6c][00101722][00000357] 6857030000 push 00000357

[00000c71][00101722][00000357] e810f7ffff call 00000386

Input_Halts = 0

[00000c76][0010172a][00000000] 83c408 add esp,+08

[00000c79][0010172a][00000000] 33c0 xor eax,eax

[00000c7b][0010172e][00100000] 5d pop ebp

[00000c7c][00101732][00000068] c3 ret

Number_of_User_Instructions(27)

Number of Instructions Executed(23721)

---5--- 2021-09-26 09:39 AM

The direct execution of P(P) halts (V2)

The execution trace of the x86 emulation of P(P) by simulating halt decider H conclusively

proves that P cannot possibly ever reach its final state of 0xc3f. This provides complete

proof that that the input to H never halts thus H(P,P)==0 is correct.

// Simplified Linz Ĥ (Linz:1990:319)

// Strachey(1965) CPL translated to C

void P(u32 x)

{

if (H(x, x))

HERE: goto HERE;

}

int main()

{

P((u32)P);

}

_P()

[00000c25](01) 55 push ebp

[00000c26](02) 8bec mov ebp,esp

[00000c28](03) 8b4508 mov eax,[ebp+08]

[00000c2b](01) 50 push eax // 2nd Param

[00000c2c](03) 8b4d08 mov ecx,[ebp+08]

[00000c2f](01) 51 push ecx // 1st Param

[00000c30](05) e820fdffff call 00000955 // call H

[00000c35](03) 83c408 add esp,+08

[00000c38](02) 85c0 test eax,eax

[00000c3a](02) 7402 jz 00000c3e

[00000c3c](02) ebfe jmp 00000c3c

[00000c3e](01) 5d pop ebp

[00000c3f](01) c3 ret

Size in bytes:(0027) [00000c3f]

_main()

[00000c45](01) 55 push ebp

[00000c46](02) 8bec mov ebp,esp

[00000c48](05) 68250c0000 push 00000c25 // push P

[00000c4d](05) e8d3ffffff call 00000c25 // call P(P)

[00000c52](03) 83c404 add esp,+04

[00000c55](02) 33c0 xor eax,eax

[00000c57](01) 5d pop ebp

[00000c58](01) c3 ret

Size in bytes:(0020) [00000c58]

machine stack stack machine assembly

address address data code language

======== ======== ======== ========= =============

[00000c45][001016d6][00000000] 55 push ebp

[00000c46][001016d6][00000000] 8bec mov ebp,esp

[00000c48][001016d2][00000c25] 68250c0000 push 00000c25 // push P

[00000c4d][001016ce][00000c52] e8d3ffffff call 00000c25 // call P0(P)

[00000c25][001016ca][001016d6] 55 push ebp // P0 begins

[00000c26][001016ca][001016d6] 8bec mov ebp,esp

[00000c28][001016ca][001016d6] 8b4508 mov eax,[ebp+08]

[00000c2b][001016c6][00000c25] 50 push eax // push P

[00000c2c][001016c6][00000c25] 8b4d08 mov ecx,[ebp+08]

[00000c2f][001016c2][00000c25] 51 push ecx // push P

[00000c30][001016be][00000c35] e820fdffff call 00000955 // call H0(P1,P1)

---6--- 2021-09-26 09:39 AM

Begin Local Halt Decider Simulation at Machine Address:c25

[00000c25][00211776][0021177a] 55 push ebp // P1 begins

[00000c26][00211776][0021177a] 8bec mov ebp,esp

[00000c28][00211776][0021177a] 8b4508 mov eax,[ebp+08]

[00000c2b][00211772][00000c25] 50 push eax // push P

[00000c2c][00211772][00000c25] 8b4d08 mov ecx,[ebp+08]

[00000c2f][0021176e][00000c25] 51 push ecx // push P

[00000c30][0021176a][00000c35] e820fdffff call 00000955 // call H1(P2,P2)

[00000c25][0025c19e][0025c1a2] 55 push ebp // P2 begins

[00000c26][0025c19e][0025c1a2] 8bec mov ebp,esp

[00000c28][0025c19e][0025c1a2] 8b4508 mov eax,[ebp+08]

[00000c2b][0025c19a][00000c25] 50 push eax // push P

[00000c2c][0025c19a][00000c25] 8b4d08 mov ecx,[ebp+08]

[00000c2f][0025c196][00000c25] 51 push ecx // push P

[00000c30][0025c192][00000c35] e820fdffff call 00000955 // call H2(P3,P3)

Local Halt Decider: Infinite Recursion Detected Simulation Stopped

In the above computation (zero based addressing) H0 aborts the P1 invocation chain.

No P(P) ever stops running unless H0 aborts its simulation of P1

Subscripts indicate that a new process context (with its own RAM, stack and registers) has

been created to simulate the virtual machine input to H. Every time H is called it creates a

new process context to simulate its inputs. The above halt status analysis is essentially

identical to the one already fully described in V1 shown above.

[00000c35][001016ca][001016d6] 83c408 add esp,+08

[00000c38][001016ca][001016d6] 85c0 test eax,eax

[00000c3a][001016ca][001016d6] 7402 jz 00000c3e

[00000c3e][001016ce][00000c52] 5d pop ebp

[00000c3f][001016d2][00000c25] c3 ret

[00000c52][001016d6][00000000] 83c404 add esp,+04

[00000c55][001016d6][00000000] 33c0 xor eax,eax

[00000c57][001016da][00100000] 5d pop ebp

[00000c58][001016de][00000084] c3 ret

Number_of_User_Instructions(34)

Number of Instructions Executed(23729)

// Simplified Linz Ĥ (Linz:1990:319)

// Strachey(1965) CPL translated to C

void P(u32 x)

{

if (H(x, x))

HERE: goto HERE;

}

int main()

{

H((u32)P, (u32)P);

P((u32)P);

}

Because the first line of main() executes H(P,P) first and then P(P) and the second line of

main() executes P(P) first and then H(P,P) the difference in the relative execution order

makes this pair of computations distinctly different computations. Distinctly different

computations can have different behavior without contradiction.

---7--- 2021-09-26 09:39 AM

Simulating partial halt decider H1 correctly decides that P(P) halts (V3)

When we create an exact copy H1 of H and invoke H1(P,P) in main() it can see that H aborts

its simulation of its input thus H1 returns 1 indicating that its input halts.

When H1(P,P) is invoked in main() its invocation order is P(P) then H(P,P).

When P(P) is invoked in main() its invocation order is P(P) then H(P,P).

Because the same invocation order is preserved H1 provides a halt status decision that is

consistent with the behavior of P(P) invoked in main().

H1(P,P) is a distinctly different computation than H(P,P) because H1 can see what H(P,P)

does yet H(P,P) cannot see anything that H1(P,P) does.

The master UTM / halt decider H1 can see everything that it simulates:

(a) P begins

(b) P calls H(P,P)

(c) H returns to P

(d) P returns to main() where it was simulated by H1.

The master UTM / halt decider H can see everything that it simulates:

(a) P begins

(b) P calls H(P,P)

(c) P begins

(e) P calls H(P,P)

H(P,P) sees that it must abort its simulation of its input or its input never halts.

void P(u32 x)

{

if (H(x, x))

HERE: goto HERE;

}

int main()

{

Output("Input_Halts = ", H1((u32)P, (u32)P));

}

x86 assembly language source-code for the above C functions.

_P()

[00000e52](01) 55 push ebp

[00000e53](02) 8bec mov ebp,esp

[00000e55](03) 8b4508 mov eax,[ebp+08]

[00000e58](01) 50 push eax

[00000e59](03) 8b4d08 mov ecx,[ebp+08]

[00000e5c](01) 51 push ecx

[00000e5d](05) e870feffff call 00000cd2 // call H

[00000e62](03) 83c408 add esp,+08

[00000e65](02) 85c0 test eax,eax

[00000e67](02) 7402 jz 00000e6b // jmp if eax == 0

[00000e69](02) ebfe jmp 00000e69 // eax != 0

[00000e6b](01) 5d pop ebp

[00000e6c](01) c3 ret

Size in bytes:(0027) [00000e6c]

---8--- 2021-09-26 09:39 AM

_main()

[00000e72](01) 55 push ebp

[00000e73](02) 8bec mov ebp,esp

[00000e75](05) 68520e0000 push 00000e52 // push P

[00000e7a](05) 68520e0000 push 00000e52 // push P

[00000e7f](05) e88efcffff call 00000b12 // call H1

[00000e84](03) 83c408 add esp,+08

[00000e87](01) 50 push eax

[00000e88](05) 6823030000 push 00000323

[00000e8d](05) e8c0f4ffff call 00000352 // call Output

[00000e92](03) 83c408 add esp,+08

[00000e95](02) 33c0 xor eax,eax

[00000e97](01) 5d pop ebp

[00000e98](01) c3 ret // exit main()

Size in bytes:(0039) [00000e98]

x86 Assembly Language Execution Trace of the above functions.

Even though H1 has identical code to H it has different behavior than H because it is

executed first. Each master UTM / halt decider can only see the user-code instructions that it

simulates. This includes the user-code that is simulated by recursive simulations of itself. H

can see lines 13-26. H1 can see lines 6-12 and lines 27-31. H1 returns to main() at line 31.

All halt deciders ignore analyzing the execution trace of any operating system source-code

because all operating system code is known to halt. The halt deciders themselves are

operating system functions.

machine stack stack machine assembly

address address data code language

======== ======== ======== ========= =============

01.[00000e72][00101a94][00000000] 55 push ebp

02.[00000e73][00101a94][00000000] 8bec mov ebp,esp

03.[00000e75][00101a90][00000e52] 68520e0000 push 00000e52 // push P

04.[00000e7a][00101a8c][00000e52] 68520e0000 push 00000e52 // push P

05.[00000e7f][00101a88][00000e84] e88efcffff call 00000b12 // call H1

Begin Local Halt Decider Simulation at Machine Address:e52

06.[00000e52][00211b34][00211b38] 55 push ebp

07.[00000e53][00211b34][00211b38] 8bec mov ebp,esp

08.[00000e55][00211b34][00211b38] 8b4508 mov eax,[ebp+08]

09.[00000e58][00211b30][00000e52] 50 push eax // push P

10.[00000e59][00211b30][00000e52] 8b4d08 mov ecx,[ebp+08]

11.[00000e5c][00211b2c][00000e52] 51 push ecx // push P

12.[00000e5d][00211b28][00000e62] e870feffff call 00000cd2 // call H

Begin Local Halt Decider Simulation at Machine Address:e52

13.[00000e52][0025c55c][0025c560] 55 push ebp

14.[00000e53][0025c55c][0025c560] 8bec mov ebp,esp

15.[00000e55][0025c55c][0025c560] 8b4508 mov eax,[ebp+08]

16.[00000e58][0025c558][00000e52] 50 push eax // push P

17.[00000e59][0025c558][00000e52] 8b4d08 mov ecx,[ebp+08]

18.[00000e5c][0025c554][00000e52] 51 push ecx // push P

19.[00000e5d][0025c550][00000e62] e870feffff call 00000cd2 // call H

20.[00000e52][002a6f84][002a6f88] 55 push ebp

21.[00000e53][002a6f84][002a6f88] 8bec mov ebp,esp

22.[00000e55][002a6f84][002a6f88] 8b4508 mov eax,[ebp+08]

23.[00000e58][002a6f80][00000e52] 50 push eax // push P

24.[00000e59][002a6f80][00000e52] 8b4d08 mov ecx,[ebp+08]

25.[00000e5c][002a6f7c][00000e52] 51 push ecx // push P

26.[00000e5d][002a6f78][00000e62] e870feffff call 00000cd2 // call H

Local Halt Decider: Infinite Recursion Detected Simulation Stopped

---9--- 2021-09-26 09:39 AM

27.[00000e62][00211b34][00211b38] 83c408 add esp,+08

28.[00000e65][00211b34][00211b38] 85c0 test eax,eax

29.[00000e67][00211b34][00211b38] 7402 jz 00000e6b

30.[00000e6b][00211b38][00000bcf] 5d pop ebp

31.[00000e6c][00211b3c][00000e52] c3 ret // return from P

32.[00000e84][00101a94][00000000] 83c408 add esp,+08

33.[00000e87][00101a90][00000001] 50 push eax

34.[00000e88][00101a8c][00000323] 6823030000 push 00000323

35.[00000e8d][00101a8c][00000323] e8c0f4ffff call 00000352 // call Output

Input_Halts = 1

36.[00000e92][00101a94][00000000] 83c408 add esp,+08

37.[00000e95][00101a94][00000000] 33c0 xor eax,eax

38.[00000e97][00101a98][00100000] 5d pop ebp

39.[00000e98][00101a9c][00000004] c3 ret // exit main()

Number_of_User_Instructions(39)

Number of Instructions Executed(626930) would be 9,357 pages of output.

Simulating partial halt decider H correctly decides that Infinite_Loop() never halts

void Infinite_Loop()

{

HERE: goto HERE;

}

int main()

{

u32 Input_Would_Halt2 = H((u32)Infinite_Loop, (u32)Infinite_Loop);

Output("Input_Would_Halt2 = ", Input_Would_Halt2);

}

_Infinite_Loop()

[00000ab0](01) 55 push ebp

[00000ab1](02) 8bec mov ebp,esp

[00000ab3](02) ebfe jmp 00000ab3

[00000ab5](01) 5d pop ebp

[00000ab6](01) c3 ret

Size in bytes:(0007) [00000ab6]

_main()

[00000c00](01) 55 push ebp

[00000c01](02) 8bec mov ebp,esp

[00000c03](01) 51 push ecx

[00000c04](05) 68b00a0000 push 00000ab0

[00000c09](05) 68b00a0000 push 00000ab0

[00000c0e](05) e84dfdffff call 00000960

[00000c13](03) 83c408 add esp,+08

[00000c16](03) 8945fc mov [ebp-04],eax

[00000c19](03) 8b45fc mov eax,[ebp-04]

[00000c1c](01) 50 push eax

[00000c1d](05) 684b030000 push 0000034b

[00000c22](05) e859f7ffff call 00000380

[00000c27](03) 83c408 add esp,+08

[00000c2a](02) 33c0 xor eax,eax

[00000c2c](02) 8be5 mov esp,ebp

[00000c2e](01) 5d pop ebp

[00000c2f](01) c3 ret

Size in bytes:(0048) [00000c2f]

---10--- 2021-09-26 09:39 AM

Execution Trace of H(Infinite_Loop, Infinite_Loop)

machine stack stack machine assembly

address address data code language

======== ======== ======== ========= =============

[00000c00][00101693][00000000] 55 push ebp

[00000c01][00101693][00000000] 8bec mov ebp,esp

[00000c03][0010168f][00000000] 51 push ecx

[00000c04][0010168b][00000ab0] 68b00a0000 push 00000ab0

[00000c09][00101687][00000ab0] 68b00a0000 push 00000ab0

[00000c0e][00101683][00000c13] e84dfdffff call 00000960

Begin Local Halt Decider Simulation at Machine Address:ab0

[00000ab0][00211733][00211737] 55 push ebp

[00000ab1][00211733][00211737] 8bec mov ebp,esp

[00000ab3][00211733][00211737] ebfe jmp 00000ab3

[00000ab3][00211733][00211737] ebfe jmp 00000ab3

Local Halt Decider: Infinite Loop Detected Simulation Stopped

[00000c13][0010168f][00000000] 83c408 add esp,+08

[00000c16][0010168f][00000000] 8945fc mov [ebp-04],eax

[00000c19][0010168f][00000000] 8b45fc mov eax,[ebp-04]

[00000c1c][0010168b][00000000] 50 push eax

[00000c1d][00101687][0000034b] 684b030000 push 0000034b

[00000c22][00101687][0000034b] e859f7ffff call 00000380

Input_Would_Halt2 = 0

[00000c27][0010168f][00000000] 83c408 add esp,+08

[00000c2a][0010168f][00000000] 33c0 xor eax,eax

[00000c2c][00101693][00000000] 8be5 mov esp,ebp

[00000c2e][00101697][00100000] 5d pop ebp

[00000c2f][0010169b][00000050] c3 ret

Number_of_User_Instructions(21)

Number of Instructions Executed(640)

---11--- 2021-09-26 09:39 AM

Simulating partial halt decider H decides that Infinite_Recursion() never halts

void Infinite_Recursion(u32 N)

{

Infinite_Recursion(N);

}

int main()

{

u32 Input_Halts = H((u32)Infinite_Recursion, 3);

Output("Input_Halts = ", Input_Halts);

}

_Infinite_Recursion()

[00000ac6](01) 55 push ebp

[00000ac7](02) 8bec mov ebp,esp

[00000ac9](03) 8b4508 mov eax,[ebp+08]

[00000acc](01) 50 push eax

[00000acd](05) e8f4ffffff call 00000ac6

[00000ad2](03) 83c404 add esp,+04

[00000ad5](01) 5d pop ebp

[00000ad6](01) c3 ret

Size in bytes:(0017) [00000ad6]

_main()

[00000c46](01) 55 push ebp

[00000c47](02) 8bec mov ebp,esp

[00000c49](01) 51 push ecx

[00000c4a](02) 6a03 push +03

[00000c4c](05) 68c60a0000 push 00000ac6

[00000c51](05) e810fdffff call 00000966

[00000c56](03) 83c408 add esp,+08

[00000c59](03) 8945fc mov [ebp-04],eax

[00000c5c](03) 8b45fc mov eax,[ebp-04]

[00000c5f](01) 50 push eax

[00000c60](05) 6857030000 push 00000357

[00000c65](05) e81cf7ffff call 00000386

[00000c6a](03) 83c408 add esp,+08

[00000c6d](02) 33c0 xor eax,eax

[00000c6f](02) 8be5 mov esp,ebp

[00000c71](01) 5d pop ebp

[00000c72](01) c3 ret

Size in bytes:(0045) [00000c72]

Execution Trace of H(Infinite_Recursion, 3)

machine stack stack machine assembly

address address data code language

======== ======== ======== ========= =============

[00000c46][001016fa][00000000] 55 push ebp

[00000c47][001016fa][00000000] 8bec mov ebp,esp

[00000c49][001016f6][00000000] 51 push ecx

[00000c4a][001016f2][00000003] 6a03 push +03

[00000c4c][001016ee][00000ac6] 68c60a0000 push 00000ac6

[00000c51][001016ea][00000c56] e810fdffff call 00000966

---12--- 2021-09-26 09:39 AM

Begin Local Halt Decider Simulation at Machine Address:ac6

[00000ac6][0021179a][0021179e] 55 push ebp

[00000ac7][0021179a][0021179e] 8bec mov ebp,esp

[00000ac9][0021179a][0021179e] 8b4508 mov eax,[ebp+08]

[00000acc][00211796][00000003] 50 push eax

[00000acd][00211792][00000ad2] e8f4ffffff call 00000ac6

[00000ac6][0021178e][0021179a] 55 push ebp

[00000ac7][0021178e][0021179a] 8bec mov ebp,esp

[00000ac9][0021178e][0021179a] 8b4508 mov eax,[ebp+08]

[00000acc][0021178a][00000003] 50 push eax

[00000acd][00211786][00000ad2] e8f4ffffff call 00000ac6

Local Halt Decider: Infinite Recursion Detected Simulation Stopped

_Infinite_Recursion() calls itself recursively with the same input. It has no escape from this

infinite recursion. H recognizes this infinite behavior pattern, aborts its simulation of

_Infinite_Recursion() and reports that this input never halts.

[00000c56][001016f6][00000000] 83c408 add esp,+08

[00000c59][001016f6][00000000] 8945fc mov [ebp-04],eax

[00000c5c][001016f6][00000000] 8b45fc mov eax,[ebp-04]

[00000c5f][001016f2][00000000] 50 push eax

[00000c60][001016ee][00000357] 6857030000 push 00000357

[00000c65][001016ee][00000357] e81cf7ffff call 00000386

Input_Halts = 0

[00000c6a][001016f6][00000000] 83c408 add esp,+08

[00000c6d][001016f6][00000000] 33c0 xor eax,eax

[00000c6f][001016fa][00000000] 8be5 mov esp,ebp

[00000c71][001016fe][00100000] 5d pop ebp

[00000c72][00101702][00000068] c3 ret

Number_of_User_Instructions(27)

Number of Instructions Executed(1240)

Infinite recursion detection criteria:

If the execution trace of function X() called by function Y() shows:

(1) Function X() is called twice in sequence from the same machine address of Y().

(2) With the same parameters to X().

(3) With no conditional branch or indexed jump instructions in Y().

(4) With no function call returns from X().

then the function call from Y() to X() is infinitely recursive.

---13--- 2021-09-26 09:39 AM

Simulating partial halt decider H decides that Factorial(3) halts

int Factorial(int n)

{

Output("Factorial(n)",n);

if (n > 1)

return n * Factorial(n - 1);

else

return 1;

}

int main()

{

Output("Input_Halts = ", H(Factorial, 3));

}

_Factorial()

[00000de2](01) 55 push ebp

[00000de3](02) 8bec mov ebp,esp

[00000de5](03) 8b4508 mov eax,[ebp+08]

[00000de8](01) 50 push eax

[00000de9](05) 6813030000 push 00000313

[00000dee](05) e85ff5ffff call 00000352

[00000df3](03) 83c408 add esp,+08

[00000df6](04) 837d0801 cmp dword [ebp+08],+01

[00000dfa](02) 7e17 jng 00000e13

[00000dfc](03) 8b4d08 mov ecx,[ebp+08]

[00000dff](03) 83e901 sub ecx,+01

[00000e02](01) 51 push ecx

[00000e03](05) e8daffffff call 00000de2

[00000e08](03) 83c404 add esp,+04

[00000e0b](04) 0faf4508 imul eax,[ebp+08]

[00000e0f](02) eb07 jmp 00000e18

[00000e11](02) eb05 jmp 00000e18

[00000e13](05) b801000000 mov eax,00000001

[00000e18](01) 5d pop ebp

[00000e19](01) c3 ret

Size in bytes:(0056) [00000e19]

_main()

[00000ea2](01) 55 push ebp

[00000ea3](02) 8bec mov ebp,esp

[00000ea5](02) 6a03 push +03

[00000ea7](05) 68e20d0000 push 00000de2

[00000eac](05) e821feffff call 00000cd2

[00000eb1](03) 83c408 add esp,+08

[00000eb4](01) 50 push eax

[00000eb5](05) 6823030000 push 00000323

[00000eba](05) e893f4ffff call 00000352

[00000ebf](03) 83c408 add esp,+08

[00000ec2](02) 33c0 xor eax,eax

[00000ec4](01) 5d pop ebp

[00000ec5](01) c3 ret

Size in bytes:(0036) [00000ec5]

---14--- 2021-09-26 09:39 AM

machine stack stack machine assembly

address address data code language

======== ======== ======== ========= =============

...[00000ea2][00101ae7][00000000] 55 push ebp

...[00000ea3][00101ae7][00000000] 8bec mov ebp,esp

...[00000ea5][00101ae3][00000003] 6a03 push +03

...[00000ea7][00101adf][00000de2] 68e20d0000 push 00000de2

...[00000eac][00101adb][00000eb1] e821feffff call 00000cd2

Begin Local Halt Decider Simulation at Machine Address:de2

...[00000de2][00211b87][00211b8b] 55 push ebp

...[00000de3][00211b87][00211b8b] 8bec mov ebp,esp

...[00000de5][00211b87][00211b8b] 8b4508 mov eax,[ebp+08]

...[00000de8][00211b83][00000003] 50 push eax

...[00000de9][00211b7f][00000313] 6813030000 push 00000313

---[00000dee][00211b7f][00000313] e85ff5ffff call 00000352

Factorial(n)3

...[00000df3][00211b87][00211b8b] 83c408 add esp,+08

...[00000df6][00211b87][00211b8b] 837d0801 cmp dword [ebp+08],+01

...[00000dfa][00211b87][00211b8b] 7e17 jng 00000e13

...[00000dfc][00211b87][00211b8b] 8b4d08 mov ecx,[ebp+08]

...[00000dff][00211b87][00211b8b] 83e901 sub ecx,+01

...[00000e02][00211b83][00000002] 51 push ecx

...[00000e03][00211b7f][00000e08] e8daffffff call 00000de2

...[00000de2][00211b7b][00211b87] 55 push ebp

...[00000de3][00211b7b][00211b87] 8bec mov ebp,esp

...[00000de5][00211b7b][00211b87] 8b4508 mov eax,[ebp+08]

...[00000de8][00211b77][00000002] 50 push eax

...[00000de9][00211b73][00000313] 6813030000 push 00000313

---[00000dee][00211b73][00000313] e85ff5ffff call 00000352

Factorial(n)2

...[00000df3][00211b7b][00211b87] 83c408 add esp,+08

...[00000df6][00211b7b][00211b87] 837d0801 cmp dword [ebp+08],+01

...[00000dfa][00211b7b][00211b87] 7e17 jng 00000e13

...[00000dfc][00211b7b][00211b87] 8b4d08 mov ecx,[ebp+08]

...[00000dff][00211b7b][00211b87] 83e901 sub ecx,+01

...[00000e02][00211b77][00000001] 51 push ecx

...[00000e03][00211b73][00000e08] e8daffffff call 00000de2

...[00000de2][00211b6f][00211b7b] 55 push ebp

...[00000de3][00211b6f][00211b7b] 8bec mov ebp,esp

...[00000de5][00211b6f][00211b7b] 8b4508 mov eax,[ebp+08]

...[00000de8][00211b6b][00000001] 50 push eax

...[00000de9][00211b67][00000313] 6813030000 push 00000313

---[00000dee][00211b67][00000313] e85ff5ffff call 00000352

Factorial(n)1

...[00000df3][00211b6f][00211b7b] 83c408 add esp,+08

...[00000df6][00211b6f][00211b7b] 837d0801 cmp dword [ebp+08],+01

...[00000dfa][00211b6f][00211b7b] 7e17 jng 00000e13

...[00000e13][00211b6f][00211b7b] b801000000 mov eax,00000001

...[00000e18][00211b73][00000e08] 5d pop ebp

...[00000e19][00211b77][00000001] c3 ret

...[00000eb1][00101ae7][00000000] 83c408 add esp,+08

...[00000eb4][00101ae3][00000001] 50 push eax

...[00000eb5][00101adf][00000323] 6823030000 push 00000323

---[00000eba][00101adf][00000323] e893f4ffff call 00000352

Input_Halts = 1

...[00000ebf][00101ae7][00000000] 83c408 add esp,+08

...[00000ec2][00101ae7][00000000] 33c0 xor eax,eax

...[00000ec4][00101aeb][00100000] 5d pop ebp

...[00000ec5][00101aef][000000c8] c3 ret

Number_of_User_Instructions(51)

Number of Instructions Executed(3714)

---15--- 2021-09-26 09:39 AM

Strachey's Impossible Program

To the Editor,

The Computer Journal.

An impossible program

Sir,

A well-known piece of folk-lore among programmers

holds that it is impossible to write a program which can

examine any other program and tell, in every case, if it

will terminate or get into a closed loop when it is run.

I have never actually seen a proof of this in print, and

though Alan Turing once gave me a verbal proof (in a

railway carriage on the way to a Conference at the

NPL in 1953), I unfortunately and promptly forgot the

details. This left me with an uneasy feeling that the

proof must be long or complicated, but in fact it is so

short and simple that it may be of interest to casual

readers. The version below uses CPL, but not in any

essential way.

Suppose T[R] is a Boolean function taking a routine

(or program) R with no formal or free variables as its

argument and that for all R, T[R] — True if R terminates

if run and that T[R] = False if R does not terminate.

Consider the routine P defined as follows

rec routine P

§L:if T[P] go to L

Return §

If T[P] = True the routine P will loop, and it will

only terminate if T[P] = False. In each case T[P] has

exactly the wrong value, and this contradiction shows

that the function T cannot exist.

Yours faithfully,

C. STRACHEY.

Churchill College,

Cambridge.

Strachey, C 1965. An impossible program The Computer Journal, Volume 7, Issue 4,

January 1965, Page 313, https://doi.org/10.1093/comjnl/7.4.313

---16--- 2021-09-26 09:39 AM

Peter Linz Ĥ applied to the Turing machine description of itself: ⟨Ĥ⟩

The following simplifies the syntax for the definition of the Linz Turing machine Ĥ, it is now a

single machine with a single start state. A simulating halt decider is embedded at .qxĤ. It has

been annotated so that it only shows Ĥ applied to ⟨Ĥ⟩, converting the variables to constants.

.q0 ⟨ ⟩ ⊢* .qx ⟨ ⟩ ⟨ ⟩ ⊢* .qy ∞ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ

if the simulated ⟨ ⟩ applied to ⟨ ⟩ halts, and Ĥ Ĥ

.q0 ⟨ ⟩ ⊢* .qx ⟨ ⟩ ⟨ ⟩ ⊢* .qn Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ

if the simulated ⟨ ⟩ applied to ⟨ ⟩ does not halt Ĥ Ĥ

Figure 12.3 Turing Machine Ĥ applied to ⟨Ĥ⟩

Ĥ copies its input ⟨Ĥ1⟩ to ⟨Ĥ2⟩ then simulates this input Ĥ1 with its input ⟨Ĥ2⟩

which copies its input ⟨Ĥ2⟩ to ⟨Ĥ3⟩ then simulates this input Ĥ2 with its input ⟨Ĥ3⟩

which copies its input ⟨Ĥ3⟩ to ⟨Ĥ4⟩ then simulates this input Ĥ3 with its input ⟨Ĥ4⟩ ...

Until the simulating halt decider at Ĥ.qx aborts the simulation of its input this input never

halts. Even though this repeating pattern is more complex (because it copies its input) than

the above x86 example of int main() { H((u32)P, (u32)P); } it is still a repeating pattern

that can be recognized by a simulating halt decider.

The transition from Ĥ.qx to Ĥ.q0 expresses the gist of the idea of infinitely nested simulation.

It is not the conventional notion of a state transition within the same machine instance.

Figure 12.4 Turing Machine Ĥ applied to ⟨Ĥ⟩ input

---17--- 2021-09-26 09:39 AM

When the original Linz H is applied to ⟨Ĥ⟩ ⟨Ĥ⟩ it sees that its input transitions to Ĥ.qn. This

provides the basis for H to transition to its final state of H.qy.

When Ĥ.qx is applied to ⟨Ĥ⟩ ⟨Ĥ⟩ it sees that none of the recursive simulations of its input ever

halt so it transtions to its final state of Ĥ.qn.

The master slave relationship from H to Ĥ.qx makes them distinctly different computations

even though they are otherwise identical and have the same input.

When a separate halt decider H is applied to its input it correctly decides that this input halts.

int main() { H1(P,P); } correctly decides that its input halts.

When an input is defined using the same halt decider that is applied to this input this

pathological self-reference error can be detected and rejected on the basis that

int main()

{

if (H1((u32)P, (u32)P) != H((u32)P, (u32)P))

OutputString("Pathological self-reference error!");

}

Copyright 2016-2021 PL Olcott

Strachey, C 1965. An impossible program The Computer Journal, Volume 7, Issue 4,

January 1965, Page 313, https://doi.org/10.1093/comjnl/7.4.313

Linz, Peter 1990. An Introduction to Formal Languages and Automata. Lexington/Toronto:

D. C. Heath and Company. (318-320)

Sipser, Michael 1997. Introduction to the Theory of Computation. Boston: PWS Publishing

Company (165-167)

---18--- 2021-09-26 09:39 AM

318

Theorem 12.1

Figure

12.1

~

12

Limits

of

Algorithmic

Computation

There does not exist any Turing machine H that behaves as required by

Definition 12.1. The halting problem is therefore undecidable.

Proof: We assume the contrary, namely that there exists

an

algorithm,

and consequently some Turing machine

H,

that solves the halting problem.

The input to H will be the description (encoded in some form)

of

M,

say

WM,

as well as the input

w.

The requirement is then that, given any

(WM,

w),

the Turing machine H will halt with either a yes

or

no answer. We achieve

this by asking that H halt in one

of

two corresponding final states, say,

qy

or

qn' The situation can be visualized by a block diagram like Figure 12.1. The

intent

of

this diagram is to indicate that, if M is started in state

qo

with input

(WM,

w),

it will eventually halt in state

qy

or

qn'

As required

by

Definition

12.1, we want H to operate according to the following rules:

if

M applied to W halts, and

if

M applied to w does not halt.

Figure

12.2

~

12.1

Some

Problems

that

Cannot

Be

Solved

by Turing

Machines

319

Next,

we modify H

to

produce a Turing machine

H'

with the structure

shown in Figure 12.2. With the added states in Figure 12.2 we want to

convey that the transitions between state qy and the new states qa and qb are

to

be

made, regardless

of

the tape symbol, in such a way that the tape

remains unchanged. The way this is done is straightforward. Comparing H

and

H'

we see that, in situations where H reaches

qy

and halts, the modified

machine

H'

will

enter

an infinite loop. Formally, the action

of

H'

is de-

scribed by

if

M applied to w halts, and

if

M applied to w does not halt.

From

H'

we construct another Turing machine

N.

This new machine

takes as input

WM,

copies it, and then behaves exactly like

H'.

Then the

action

of

N

is

such that

if

M applied to W M halts, and

if

M applied to

WM

does

not

halt.

320

~

12

Limits

of

Algorithmic Computation

Now

Ii is a Turing machine, so that it will have some description in I*,

say

w.

This string, in addition to being the description

of

Ii can also be used

as input string. We

can

therefore legitimately ask what would happen if Ii is

applied to

w.

From

the above, identifying M with

Ii,

we get

if Ii applied to w halts, and

A *

00

qow r

iI

'

if Ii applied to w does not halt. This is clearly nonsense. The contradiction

tells us that

our

assumption

of

the existence

of

H,

and hence the assump-

tion

of

the decidability

of

the halting problem, must be false. •