(* Title: thys/TuringDecidable.thy Author: Franz Regensburger (FABR) 02/2022 *) section ‹Turing Decidability› theory TuringDecidable imports OneStrokeTM Turing_HaltingConditions begin (* -------------------------------------------------------------------------- *) (* declare adjust.simps[simp del] declare seq_tm.simps [simp del] declare shift.simps[simp del] declare composable_tm.simps[simp del] declare step.simps[simp del] declare steps.simps[simp del] *) subsection ‹Turing Decidable Sets and Relations of natural numbers› text ‹We use lists of natural numbers in order to model tuples of arity @{term k} of natural numbers, where @{term "0 ≤ (k::nat)"}. › (* For a relation R of @⦃term k⦄-ary tuples use a set nls of nat lists, where each of its elements nl (which is a nat list) has length k. (n1, ... , nk) ∈ R ⟷ [<[n1, ... , nk]>] ∈ nls . For a plain set of natural numbers S simply use a set of singleton nat lists nls where n ∈ S ⟷ [<n>] ∈ nls. *) text ‹Now, we define the notion of {\em Turing Decidable Sets and Relations}. In our definition, we directly relate decidability of sets and relations to Turing machines and do not adhere to the formal concept of a characteristic function. However, the notion of a characteristic function is introduced in the theory about Turing computable functions. › definition turing_decidable :: "(nat list) set ⇒ bool" where "turing_decidable nls ≡ (∃D. (∀nl. (nl ∈ nls ⟶ ⦃(λtap. tap = ([], <nl>))⦄ D ⦃(λtap. ∃k l. tap = (Bk ↑ k, <1::nat> @ Bk↑ l))⦄) ∧ (nl ∉ nls ⟶ ⦃(λtap. tap = ([], <nl>))⦄ D ⦃(λtap. ∃k l. tap = (Bk ↑ k, <0::nat> @ Bk↑ l))⦄) ))" (* This is for documentation and explanation: turing_decidable_unfolded_into_TMC_yields_conditions *) lemma turing_decidable_unfolded_into_TMC_yields_conditions: "turing_decidable nls ≡ (∃D. (∀nl. (nl ∈ nls ⟶ TMC_yields_num_res D nl (1::nat) ) ∧ (nl ∉ nls ⟶ TMC_yields_num_res D nl (0::nat) ) ))" unfolding TMC_yields_num_res_unfolded_into_Hoare_halt by (simp add: turing_decidable_def) (* --------------------------------------------------------------------------------------------- *) subsection ‹Examples for decidable sets of natural numbers› text ‹Using the machine OneStrokeTM as a decider we are able to proof the decidability of the empty set. Moreover, in the theory about Halting Problems, we will show that there are undecidable sets as well. Thus, the notion of Turing Decidability is not a trivial concept. › lemma turing_decidable_empty_set_iff: "turing_decidable {} = (∃D. ∀(nl:: nat list). ⦃(λtap. tap = ([], <nl>))⦄ D ⦃(λtap. ∃k l. tap = (Bk ↑ k, [Oc] @ Bk ↑l))⦄)" unfolding turing_decidable_def by (simp add: tape_of_nat_def) theorem turing_decidable_empty_set: "turing_decidable {}" by (rule turing_decidable_empty_set_iff[THEN iffD2]) (blast intro: tm_onestroke_total_correctness) (* For demo in classes *) (* lemma tm_onestroke_total_correctness': "∀nl. TMC_yields_num_res tm_onestroke nl (0::nat)" unfolding TMC_yields_num_res_unfolded_into_Hoare_halt using tm_onestroke_total_correctness by (simp add: tape_of_nat_def) theorem turing_decidable_empty_set': "(∀nl. (nl ∈ {} ⟶ TMC_yields_num_res tm_onestroke nl (1::nat) ) ∧ (nl ∉ {} ⟶ TMC_yields_num_res tm_onestroke nl (0::nat) ) )" unfolding TMC_yields_num_res_unfolded_into_Hoare_halt proof - show "∀nl. (nl ∈ {} ⟶ ⦃λtap. tap = ([], <nl::nat list>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <1::nat> @ Bk ↑ l)⦄) ∧ (nl ∉ {} ⟶ ⦃λtap. tap = ([], <nl::nat list>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <0::nat> @ Bk ↑ l)⦄)" proof fix nl:: "nat list" show "(nl ∈ {} ⟶ ⦃λtap. tap = ([], <nl>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <1::nat> @ Bk ↑ l)⦄) ∧ (nl ∉ {} ⟶ ⦃λtap. tap = ([], <nl>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <0::nat> @ Bk ↑ l)⦄)" proof show "nl ∈ {} ⟶ ⦃λtap. tap = ([], <nl>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <1::nat> @ Bk ↑ l)⦄" proof assume "nl ∈ {}" (* nothing can ever be an element of the empty set {}, thus contradiction *) then have False by auto then show "⦃λtap. tap = ([], <nl>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <1::nat> @ Bk ↑ l)⦄" by auto qed next show "nl ∉ {} ⟶ ⦃λtap. tap = ([], <nl>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <0::nat> @ Bk ↑ l)⦄" proof assume "nl ∉ {}" have "∀nl.⦃λtap. tap = ([], <nl::nat list>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <0::nat> @ Bk ↑ l)⦄" using TMC_yields_num_res_unfolded_into_Hoare_halt tm_onestroke_total_correctness' by blast then show "⦃λtap. tap = ([], <nl>)⦄ tm_onestroke ⦃λtap. ∃k l. tap = (Bk ↑ k, <0::nat> @ Bk ↑ l)⦄" by auto qed qed qed qed corollary "turing_decidable {}" unfolding turing_decidable_unfolded_into_TMC_yields_conditions using turing_decidable_empty_set' by auto *) (* ---------------------------------------------------- *) (* ENHANCE: add a means for turing_semi_decidable *) (* ---------------------------------------------------- *) (* ---------------------------------------------------- *) (* ENHANCE: add a means for dove-tailing *) (* ---------------------------------------------------- *) (* ---------------------------------------------------- *) (* ENHANCE: prove advanced theorems about decidability *) (* ---------------------------------------------------- *) (* - Step counter theorem ;aka (s,m,n) theorem *) (* - Rice's theorem for Turing Machines *) (* ---------------------------------------------------- *) end