Theory TuringUnComputable_H2
subsection ‹Existence of an uncomputable Function›
theory TuringUnComputable_H2
imports
CopyTM
DitherTM
begin
subsubsection ‹Undecidability of the General Halting Problem H, Variant 2, revised version›
text ‹
This variant of the decision problem H is discussed in the book
Computability and Logic by Boolos, Burgess and Jeffrey~\<^cite>‹"Boolos07"› in chapter 4.
The proof makes use of the TMs @{term "tm_copy"} and @{term "tm_dither"}.
In \<^cite>‹"Boolos07"›, the machines are called {\em copy} and {\em dither}.
›
fun dummy_code :: "tprog0 ⇒ nat"
where "dummy_code tp = 0"
locale hph2 =
fixes code :: "instr list ⇒ nat"
begin
text ‹The function @{term dummy_code} is a witness that the locale hph2 is inhabited.
Note: there just has to be some function with the correct type since we did not
specify any axioms for the locale. The behaviour of the instance of the locale
function code does not matter at all.
This detail differs from the locale hpk, where a locale axiom specifies that the
coding function has to be injective.
Obviously, the entire logical argument of the undecidability proof H2
relies on the combination of the machines @{term "tm_copy"} and @{term "tm_dither"}.
›
interpretation dummy_code: hph2 "dummy_code :: tprog0 ⇒ nat"
proof unfold_locales
qed
text ‹The next lemma plays a crucial role in the proof by contradiction.
Due to our general results about trailing blanks on the left tape,
we are able to compensate for the additional blank, which is a mandatory
by-product of the @{term "tm_copy"}.
›
lemma add_single_BK_to_left_tape:
"⦃λtap. tap = ([] , <(m::nat, m)> ) ⦄ p ⦃λtap. ∃k l. tap = (Bk ↑ k, r' @Bk↑l )⦄
⟹
⦃λtap. tap = ([Bk], <(m , m)> ) ⦄ p ⦃λtap. ∃k l. tap = (Bk ↑ k, r' @Bk↑l )⦄"
proof -
assume "⦃λtap. tap = ([], <(m::nat, m)> ) ⦄ p ⦃λtap. ∃k l. tap = (Bk ↑ k, r' @Bk↑l)⦄"
then have "∀z.⦃λtap. tap = (Bk ↑ z, <(m::nat, m)> ) ⦄ p ⦃λtap. ∃k l. tap = (Bk ↑ k, r' @Bk↑l)⦄"
using Hoare_halt_add_Bks_left_tape_L1 Hoare_halt_add_Bks_left_tape by blast
then have "⦃λtap. tap = (Bk ↑ 1, <(m::nat, m)> ) ⦄ p ⦃λtap. ∃k l. tap = (Bk ↑ k, r' @Bk↑l)⦄"
by blast
then show ?thesis
by (simp add: Hoare_haltE Hoare_haltI)
qed
text ‹Definition of the General Halting Problem H2.›
definition H2 :: "((instr list) × (nat list)) set"
where
"H2 ≡ {(tm,nl). TMC_has_num_res tm nl }"
text ‹No Turing Machine is able to decide the General Halting Problem H2.›
lemma existence_of_decider_H2D0_for_H2_imp_False:
assumes "∃H2D0'. (∀nl (tm::instr list).
((tm,nl) ∈ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0' ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc] @ Bk↑l)⦄)
∧ ((tm,nl) ∉ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0' ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄) )"
shows False
proof -
from assms obtain H2D0' where
w_H2D0': "(∀nl (tm::instr list).
((tm,nl) ∈ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0' ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc] @Bk↑l)⦄)
∧ ((tm,nl) ∉ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0' ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄) )"
by blast
then have "composable_tm0 (mk_composable0 H2D0') ∧ (∀nl (tm::instr list).
((tm,nl) ∈ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ mk_composable0 H2D0' ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc] @Bk↑l)⦄)
∧ ((tm,nl) ∉ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ mk_composable0 H2D0' ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄) )"
by (auto simp add: Hoare_halt_tm_impl_Hoare_halt_mk_composable0_cell_list composable_tm0_mk_composable0 )
then have "∃H2D0. composable_tm0 H2D0 ∧ (∀nl (tm::instr list).
((tm,nl) ∈ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc] @Bk↑l)⦄)
∧ ((tm,nl) ∉ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄) )"
by blast
then obtain H2D0 where w_H2D0: "composable_tm0 H2D0 ∧ (∀nl (tm::instr list).
((tm,nl) ∈ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc] @Bk↑l)⦄)
∧ ((tm,nl) ∉ H2 ⟶⦃λtap. tap = ([], <(code tm, nl)>)⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄) )"
by blast
define tm_contra where "tm_contra = (tm_copy |+| H2D0 |+| tm_dither)"
from w_H2D0 have H_composable: "composable_tm0 (tm_copy |+| H2D0)" by auto
show False
proof (cases "(tm_contra, [code tm_contra]) ∈ H2")
case True
then have "(tm_contra, [code tm_contra]) ∈ H2" .
then have inH2: "TMC_has_num_res tm_contra [code tm_contra]"
by (auto simp add: H2_def)
show False
proof -
define P1 where "P1 ≡ λtap. tap = ([]::cell list, <code tm_contra>)"
define P2 where "P2 ≡ λtap. tap = ([Bk]::cell list, <(code tm_contra, code tm_contra)>)"
define Q3 where "Q3 ≡ λtap. ∃k l. tap = (Bk ↑ k, [Oc] @Bk↑l)"
have first: "⦃P1⦄ (tm_copy |+| H2D0) ⦃Q3⦄"
proof (cases rule: Hoare_plus_halt)
case A_halt
show "⦃P1⦄ tm_copy ⦃P2⦄" unfolding P1_def P2_def tape_of_nat_def
by (rule tm_copy_correct)
next
case B_halt
from ‹(tm_contra, [code tm_contra]) ∈ H2› and w_H2D0
have "⦃λtap. tap = ([], <(code tm_contra, [code tm_contra])> ) ⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc] @Bk↑l)⦄"
by auto
then have "⦃λtap. tap = ([], <(code tm_contra, code tm_contra) > ) ⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc] @Bk↑l)⦄"
by (simp add: Hoare_haltE Hoare_haltI tape_of_list_def tape_of_prod_def)
then show "⦃P2⦄ H2D0 ⦃Q3⦄"
unfolding P2_def Q3_def
using add_single_BK_to_left_tape
by blast
next
show "composable_tm0 tm_copy" by auto
qed
have second: "⦃Q3⦄ tm_dither ↑" unfolding Q3_def
using tm_dither_loops''
by (simp add: tape_of_nat_def )
have "⦃P1⦄ tm_contra ↑"
unfolding tm_contra_def
by (rule Hoare_plus_unhalt[OF first second H_composable])
then have "¬TMC_has_num_res tm_contra [code tm_contra]"
unfolding P1_def
by (metis (mono_tags) Hoare_halt_impl_not_Hoare_unhalt
TMC_has_num_res_def inH2 tape_of_list_def tape_of_nat_list.simps(2))
with inH2 show False by auto
qed
next
case False
then have "(tm_contra, [code tm_contra]) ∉ H2" .
then have not_inH2: "¬TMC_has_num_res tm_contra [code tm_contra]"
by (auto simp add: H2_def)
show False
proof -
define P1 where "P1 ≡ λtap. tap = ([]::cell list, <code tm_contra>)"
define P2 where "P2 ≡ λtap. tap = ([Bk], <(code tm_contra, code tm_contra)>)"
define P3 where "P3 ≡ λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l )"
have first: "⦃P1⦄ (tm_copy |+| H2D0) ⦃P3⦄"
proof (cases rule: Hoare_plus_halt)
case A_halt
show "⦃P1⦄ tm_copy ⦃P2⦄" unfolding P1_def P2_def tape_of_nat_def
by (rule tm_copy_correct)
next
case B_halt
from ‹(tm_contra, [code tm_contra]) ∉ H2› and w_H2D0
have "⦃λtap. tap = ([], <(code tm_contra, [code tm_contra])> ) ⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄"
by auto
then have "⦃λtap. tap = ([], <(code tm_contra, code tm_contra) > ) ⦄ H2D0 ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄"
by (simp add: Hoare_haltE Hoare_haltI tape_of_list_def tape_of_prod_def)
then show "⦃P2⦄ H2D0 ⦃P3⦄"
unfolding P2_def P3_def
by (rule add_single_BK_to_left_tape)
next
show "composable_tm0 tm_copy" by simp
qed
from tm_dither_halts
have "⦃λtap. tap = ([], [Oc, Oc])⦄ tm_dither ⦃λtap. ∃k l. tap = (Bk ↑ k, [Oc, Oc] @Bk↑l)⦄"
proof -
have "∀n. ∃l. steps0 (1, Bk ↑ n, [Oc, Oc]) tm_dither (Suc 1) = (0, Bk ↑ n, [Oc, Oc] @Bk↑l)"
by (metis One_nat_def tm_dither_halts_aux Suc_1 append.right_neutral replicate.simps(1) )
then show ?thesis
using Hoare_halt_add_Bks_left_tape_L2 Hoare_halt_del_Bks_left_tape by blast
qed
then have second: "⦃P3⦄ tm_dither ⦃P3⦄" unfolding P3_def
proof -
have "Oc # [Oc] = [Oc, Oc]"
using One_nat_def replicate_Suc tape_of_nat_def by fastforce
then show "⦃λp. ∃n na. p = (Bk ↑ n, [Oc, Oc] @ Bk ↑ na)⦄ tm_dither ⦃λp. ∃n na. p = (Bk ↑ n, [Oc, Oc] @ Bk ↑ na)⦄"
using tm_dither_halts'' by presburger
qed
with first have "⦃P1⦄ tm_contra ⦃P3⦄"
unfolding tm_contra_def
proof (rule Hoare_plus_halt)
from H_composable show "composable_tm0 (tm_copy |+| H2D0)" by auto
qed
then have "TMC_has_num_res tm_contra [code tm_contra]" unfolding P1_def P3_def
by (simp add: Hoare_haltE Hoare_haltI Hoare_halt_with_OcOc_imp_std_tap tape_of_list_def)
with not_inH2
show ?thesis by auto
qed
qed
qed
text ‹Note: since we did not formalize the concept of Turing Computable Functions and
Characteristic Functions of sets yet, we are (at the moment) not able to formalize the existence
of an uncomputable function, namely the characteristic function of the set H2.
Another caveat is the fact that the set H2 has type @{typ "((instr list) × (nat list)) set"}.
This is in contrast to the classical formalization of decision problems, where the sets discussed
only contain tuples respectively lists of natural numbers.
›
end
end