section‹Well-formedness of lists\label{s:tm-wellformed}›
theory Wellformed imports Symbol_Ops Lists_Lists begin
text‹
the representations introduced in Section~\ref{s:tm-numlist} and
~\ref{s:tm-numlistlist}, not every symbol sequence over @{text "01∣"}
a list of numbers, and not every symbol sequence over @{text 01∣♯"} represents a list of lists of numbers. In this section we prove
for symbol sequences to represent such lists and devise Turing machines
check these criteria efficiently. ›
subsection‹A criterion for well-formed lists›
text‹
the definition of @{const numlist} it is easy to see that a symbol sequence
a list of numbers is either empty or not, and that in the latter
it ends with a @{text "∣"} symbol. Moreover it can only contain the symbols
{text "01∣"} and cannot contain the symbol sequence @{text "0∣"} because
number representations cannot end in @{text 0}. That these properties
not only necessary but also sufficient for the symbol sequence to represent
list of numbers is shown in this section.
symbol sequence is well-formed if it represents a list of numbers. ›
lemma numlist_wf_append: assumes"numlist_wf xs"and"numlist_wf ys" shows"numlist_wf (xs @ ys)" proof - obtain ms ns where"numlist ms = xs"and"numlist ns = ys" using assms numlist_wf_def by auto thenhave"numlist (ms @ ns) = xs @ ys" using numlist_append by simp thenshow ?thesis using numlist_wf_def by auto qed
lemma numlist_wf_canonical: assumes"canonical xs" shows"numlist_wf (xs @ [∣])" proof - obtain n where"canrepr n = xs" using assms canreprI by blast thenhave"numlist [n] = xs @ [∣]" using numlist_def by simp thenshow ?thesis using numlist_wf_def by auto qed
text‹
-formed symbol sequences can be unambiguously decoded to lists of numbers. ›
definition zs_numlist :: "symbol list ==> nat list"where "zs_numlist zs ≡ THE ns. numlist ns = zs"
lemma zs_numlist_ex1: assumes"numlist_wf zs" shows"∃!ns. numlist ns = zs" using assms numlist_wf_def numlist_inj by blast
lemma numlist_zs_numlist: assumes"numlist_wf zs" shows"numlist (zs_numlist zs) = zs" using assms zs_numlist_def zs_numlist_ex1 by (smt (verit, del_insts) the_equality)
text‹
the number of occurrences of an element in a list: ›
fun count :: "nat list ==> nat ==> nat"where "count [] z = 0" | "count (x # xs) z = (if x = z then 1 else 0) + count xs z"
lemma count_append: "count (xs @ ys) z = count xs z + count ys z" by (induction xs) simp_all
lemma count_0: "count xs z = 0 ⟷ (∀x∈set xs. x ≠ z)" proof show"count xs z = 0 ==>∀x∈set xs. x ≠ z" by (induction xs) auto show"∀x∈set xs. x ≠ z ==> count xs z = 0" by (induction xs) auto qed
lemma count_gr_0_take: assumes"count xs z > 0" shows"∃j. j < length xs ∧ xs ! j = z ∧ (∀i<j. xs ! i ≠ z) ∧ count (take (Suc j) xs) z = 1 ∧ count (drop (Suc j) xs) z = count xs z - 1" proof - let ?P = "λi. i < length xs ∧ xs ! i = z" have ex: "∃i. ?P i" using assms(1) count_0 by (metis bot_nat_0.not_eq_extremum in_set_conv_nth)
define j where"j = Least ?P" have1: "j < length xs" using j_def ex by (metis (mono_tags, lifting) LeastI) moreoverhave2: "xs ! j = z" using j_def ex by (metis (mono_tags, lifting) LeastI) moreoverhave3: "∀i<j. xs ! i ≠ z" using j_def ex 1 not_less_Least order_less_trans by blast moreoverhave4: "count (take (Suc j) xs) z = 1" proof - have"∀x∈set (take j xs). x ≠ z" using31by (metis in_set_conv_nth length_take less_imp_le_nat min_absorb2 nth_take) thenhave"count (take j xs) z = 0" using count_0 by simp moreoverhave"count [xs ! j] z = 1" using2by simp moreoverhave"take (Suc j) xs = take j xs @ [xs ! j]" using1 take_Suc_conv_app_nth by auto ultimatelyshow"count (take (Suc j) xs) z = 1" using count_append by simp qed moreoverhave"count (drop (Suc j) xs) z = count xs z - 1" proof - have"xs = take (Suc j) xs @ drop (Suc j) xs" using1by simp thenshow ?thesis using count_append 4by (metis add_diff_cancel_left') qed ultimatelyshow ?thesis by auto qed
definition has2 :: "symbol list ==> symbol ==> symbol ==> bool"where "has2 xs y z ≡∃i<length xs - 1. xs ! i = y ∧ xs ! (Suc i) = z"
lemma not_has2_take: assumes"¬ has2 xs y z" shows"¬ has2 (take m xs) y z" proof (rule ccontr) let ?ys = "take m xs" assume"¬¬ has2 ?ys y z" thenhave"has2 ?ys y z" by simp thenhave"has2 xs y z" using has2_def by fastforce thenshow False using assms by simp qed
lemma not_has2_drop: assumes"¬ has2 xs y z" shows"¬ has2 (drop m xs) y z" proof (rule ccontr) let ?ys = "drop m xs" assume"¬¬ has2 ?ys y z" thenhave"has2 ?ys y z" by simp thenhave"has2 xs y z" using has2_def by fastforce thenshow False using assms by simp qed
lemma numlist_wf_has2: assumes"proper_symbols xs""symbols_lt 5 xs""¬ has2 xs 0∣""xs ≠ [] ⟶ last xs = ∣" shows"numlist_wf xs" using assms proof (induction"count xs ∣" arbitrary: xs) case0 thenhave"xs = []" using count_0 by simp thenshow ?case using numlist_wf_def numlist_Nil by blast next case (Suc n) thenobtain j :: nat where j: "j < length xs" "xs ! j = ∣" "∀i<j. xs ! i ≠∣" "count (take (Suc j) xs) ∣ = 1" "count (drop (Suc j) xs) ∣ = count xs ∣ - 1" by (metis count_gr_0_take zero_less_Suc) thenhave"xs ≠ []" by auto thenhave"last xs = ∣" using Suc.prems by simp
let ?ys = "drop (Suc j) xs" have"count ?ys ∣ = n" using j(5) Suc by simp moreoverhave"proper_symbols ?ys" using Suc.prems by simp moreoverhave"symbols_lt 5 ?ys" using Suc.prems by simp moreoverhave"¬ has2 ?ys 0∣" using not_has2_drop Suc.prems(3) by simp moreoverhave"?ys ≠ [] ⟶ last ?ys = ∣" using j by (simp add: ‹last xs = ∣›) ultimatelyhave wf_ys: "numlist_wf ?ys" using Suc by simp
let ?zs = "take j xs" have"canonical ?zs" proof - have"?zs ! i ≥0"if"i < length ?zs"for i using that Suc.prems(1) j by (metis One_nat_def Suc_1 Suc_leI length_take min_less_iff_conj nth_take) moreoverhave"?zs ! i ≤1"if"i < length ?zs"for i proof - have"?zs ! i < ∣" using that Suc.prems(1,2) j by (metis eval_nat_numeral(3) length_take less_Suc_eq_le min_less_iff_conj nat_less_le nth_take) thenshow ?thesis by simp qed ultimatelyhave"bit_symbols ?zs" by fastforce moreoverhave"?zs = [] ∨ last ?zs = 1" proof (cases "?zs = []") case True thenshow ?thesis by simp next case False thenhave"last ?zs = ?zs ! (j - 1)" by (metis add_diff_inverse_nat j(1) last_length length_take less_imp_le_nat less_one
min_absorb2 plus_1_eq_Suc take_eq_Nil) thenhave last: "last ?zs = xs ! (j - 1)" using False by simp have"xs ! (j - 1) ≠∣" using j(3) False by simp moreoverhave"xs ! (j - 1) < ♯" using Suc.prems(2) j(1) by simp moreoverhave"xs ! (j - 1) ≥0" using Suc.prems(1) j(1) by (metis One_nat_def Suc_1 Suc_leI less_imp_diff_less) moreoverhave"xs ! (j - 1) ≠0" proof (rule ccontr) assume"¬ xs ! (j - 1) ≠0" thenhave"xs ! (j - 1) = 0" by simp moreoverhave"xs ! j = ∣" using j by simp ultimatelyhave"has2 xs 0∣" using has2_def j False by (metis (no_types, lifting) Nat.lessE add_diff_cancel_left' less_Suc_eq_0_disj not_less_eq plus_1_eq_Suc take_eq_Nil) thenshow False using Suc.prems(3) by simp qed ultimatelyhave"xs ! (j - 1) = 1" by simp thenhave"last ?zs = 1" using last by simp thenshow ?thesis by simp qed ultimatelyshow"canonical ?zs" using canonical_def by simp qed
let ?ts = "take (Suc j) xs" have"?ts = ?zs @ [∣]" using j by (metis take_Suc_conv_app_nth) thenhave"numlist_wf ?ts" using numlist_wf_canonical `canonical ?zs` by simp moreoverhave"xs = ?ts @ ?ys" by simp ultimatelyshow"numlist_wf xs" using wf_ys numlist_wf_append by fastforce qed
lemma last_numlist_4: "numlist ns ≠ [] ==> last (numlist ns) = ∣" proof (induction ns) case Nil thenshow ?case using numlist_def by simp next case (Cons n ns) thenshow ?case using numlist_def by (cases "numlist ns = []") simp_all qed
lemma numlist_not_has2: assumes"i < length (numlist ns) - 1"and"numlist ns ! i = 0" shows"numlist ns ! (Suc i) ≠∣" using assms proof (induction ns arbitrary: i) case Nil thenshow ?case by (simp add: numlist_Nil) next case (Cons n ns) show"numlist (n # ns) ! (Suc i) ≠∣" proof (cases "i < length (numlist [n])") case True have"numlist (n # ns) ! i = (numlist [n] @ numlist ns) ! i" using numlist_def by simp thenhave"numlist (n # ns) ! i = numlist [n] ! i" using True by (simp add: nth_append) thenhave"numlist (n # ns) ! i = (canrepr n @ [∣]) ! i" using numlist_def by simp moreoverhave"numlist (n # ns) ! i = 0" using Cons by simp ultimatelyhave"(canrepr n @ [∣]) ! i = 0" by simp moreoverhave"(canrepr n @ [∣]) ! (length (canrepr n @ [∣]) - 1) = ∣" by simp ultimatelyhave"i ≠ length (canrepr n @ [∣]) - 1" by auto thenhave *: "i ≠ length (numlist [n]) - 1" using numlist_def by simp
have3: "canrepr n ! j = numlist (n # ns) ! j"if"j < nlength n"for j proof - have j: "j < length (numlist [n])" using that numlist_def by simp have"numlist (n # ns) ! j = (numlist [n] @ numlist ns) ! j" using numlist_def by simp thenhave"numlist (n # ns) ! j = numlist [n] ! j" using j by (simp add: nth_append) thenhave"numlist (n # ns) ! j = (canrepr n @ [∣]) ! j" using numlist_def by simp thenshow ?thesis by (simp add: nth_append that) qed
have neq0: "n ≠ 0" proof - have"length (numlist [0]) = 1" using numlist_def by simp thenshow ?thesis using * True by (metis diff_self_eq_0 less_one) qed thenhave"i < length (numlist [n]) - 1" using * True by simp thenhave"i < length (canrepr n @ [∣]) - 1" using numlist_def by simp thenhave"i < length (canrepr n)" by simp thenhave"canrepr n ! i = 0" by (metis ‹(canrepr n @ [∣]) ! i = 0› nth_append) moreoverhave"last (canrepr n) ≠0" using canonical_canrepr canonical_def by (metis neq0 length_0_conv n_not_Suc_n nlength_0 numeral_2_eq_2 numeral_3_eq_3) ultimatelyhave"i ≠ nlength n - 1" by (metis ‹i < nlength n› last_conv_nth less_zeroE list.size(3)) thenhave"i < nlength n - 1" using‹i < nlength n›by linarith thenhave"Suc i < nlength n" by simp thenhave"canrepr n ! Suc i ≤1" using bit_symbols_canrepr by fastforce moreoverhave"canrepr n ! Suc i = numlist (n # ns) ! Suc i" using3‹Suc i < nlength n›by blast ultimatelyshow ?thesis by simp next case False let ?i = "i - length (numlist [n])" have"numlist (n # ns) ! i = (numlist [n] @ numlist ns) ! i" using numlist_def by simp thenhave"numlist (n # ns) ! i = numlist ns ! ?i" using False by (simp add: nth_append) thenhave"numlist ns ! ?i = 0" using Cons by simp moreoverhave"?i < length (numlist ns) - 1" proof - have"length (numlist (n # ns)) = length (numlist [n]) + length (numlist ns)" using numlist_def by simp thenshow ?thesis using False Cons by simp qed ultimatelyhave"numlist ns ! Suc ?i ≠∣" using Cons by simp moreoverhave"numlist (n # ns) ! Suc i = numlist ns ! Suc ?i" using False numlist_append by (smt (verit, del_insts) Suc_diff_Suc Suc_lessD append_Cons append_Nil diff_Suc_Suc not_less_eq nth_append) ultimatelyshow ?thesis by simp qed qed
lemma numlist_wf_has2': assumes"numlist_wf xs" shows"proper_symbols_lt 5 xs ∧¬ has2 xs 0∣∧ (xs ≠ [] ⟶ last xs = ∣)" proof - obtain ns where ns: "numlist ns = xs" using numlist_wf_def assms by auto have"proper_symbols xs" using proper_symbols_numlist ns by auto moreoverhave"symbols_lt 5 xs" using ns numlist_234 by (smt (verit, best) One_nat_def Suc_1 eval_nat_numeral(3) in_mono insertE less_Suc_eq_le
linorder_le_less_linear nle_le not_less0 nth_mem numeral_less_iff semiring_norm(76)
semiring_norm(89) semiring_norm(90) singletonD) moreoverhave"¬ has2 xs 0∣" using numlist_not_has2 ns has2_def by auto moreoverhave"xs ≠ [] ⟶ last xs = ∣" using last_numlist_4 ns by auto ultimatelyshow ?thesis by simp qed
lemma numlist_wf_iff: "numlist_wf xs ⟷ proper_symbols_lt 5 xs ∧¬ has2 xs 0∣∧ (xs ≠ [] ⟶ last xs = ∣)" using numlist_wf_has2 numlist_wf_has2' by auto
subsection‹A criterion for well-formed lists of lists›
text‹
criterion for lists of lists of numbers is similar to the one for lists of
. A non-empty symbol sequence must end in @{text ♯}. All symbols must be
@{text "01∣♯"} and the sequences @{text "0∣"}, @{text "0♯"}, and @{text 1♯"} are forbidden.
symbol sequence is well-formed if it represents a list of lists of numbers. ›
lemma numlistlist_wf_append: assumes"numlistlist_wf xs"and"numlistlist_wf ys" shows"numlistlist_wf (xs @ ys)" proof - obtain ms ns where"numlistlist ms = xs"and"numlistlist ns = ys" using assms numlistlist_wf_def by auto thenhave"numlistlist (ms @ ns) = xs @ ys" using numlistlist_append by simp thenshow ?thesis using numlistlist_wf_def by auto qed
lemma numlistlist_wf_numlist_wf: assumes"numlist_wf xs" shows"numlistlist_wf (xs @ [♯])" proof - obtain ns where"numlist ns = xs" using assms numlist_wf_def by auto thenhave"numlistlist [ns] = xs @ [♯]" using numlistlist_def by simp thenshow ?thesis using numlistlist_wf_def by auto qed
lemma numlistlist_wf_has2: assumes"proper_symbols xs""symbols_lt 6 xs""xs ≠ [] ⟶ last xs = ♯" and"¬ has2 xs 0∣" and"¬ has2 xs 0♯" and"¬ has2 xs 1♯" shows"numlistlist_wf xs" using assms proof (induction"count xs ♯" arbitrary: xs) case0 thenhave"xs = []" using count_0 by simp thenshow ?case using numlistlist_wf_def numlistlist_Nil by auto next case (Suc n) thenobtain j :: nat where j: "j < length xs" "xs ! j = ♯" "∀i<j. xs ! i ≠♯" "count (take (Suc j) xs) ♯ = 1" "count (drop (Suc j) xs) ♯ = count xs ♯ - 1" by (metis count_gr_0_take zero_less_Suc) thenhave"xs ≠ []" by auto thenhave"last xs = ♯" using Suc.prems by simp let ?ys = "drop (Suc j) xs" have"count ?ys ♯ = n" using j(5) Suc by simp moreoverhave"proper_symbols ?ys" using Suc.prems(1) by simp moreoverhave"symbols_lt 6 ?ys" using Suc.prems(2) by simp moreoverhave"?ys ≠ [] ⟶ last ?ys = ♯" using j by (simp add: ‹last xs = ♯›) moreoverhave"¬ has2 ?ys 0∣" using not_has2_drop Suc.prems(4) by simp moreoverhave"¬ has2 ?ys 0♯" using not_has2_drop Suc.prems(5) by simp moreoverhave"¬ has2 ?ys 1♯" using not_has2_drop Suc.prems(6) by simp ultimatelyhave wf_ys: "numlistlist_wf ?ys" using Suc by simp
let ?zs = "take j xs" have len: "length ?zs = j" using j(1) by simp have"numlist_wf ?zs" proof - have"proper_symbols ?zs" using Suc.prems(1) by simp moreoverhave"symbols_lt 5 ?zs" proof standard+ fix i :: nat assume"i < length ?zs" thenhave"i < j" using j by simp thenhave"?zs ! i < 6" using Suc.prems(2) j by simp moreoverhave"?zs ! i ≠♯" using `i < j` j by simp ultimatelyshow"?zs ! i < ♯" by simp qed moreoverhave"¬ has2 ?zs 0∣" using not_has2_take Suc.prems(4) by simp moreoverhave"?zs ≠ [] ⟶ last ?zs = ∣" proof assume neq_Nil: "?zs ≠ []" thenhave"j > 0" by simp moreoverhave"xs ! j = ♯" using j by simp ultimatelyhave"xs ! Suc (j - 1) = ♯" by simp moreoverhave"j - 1 < length xs - 1" by (simp add: Suc_leI ‹0 < j› diff_less_mono j(1)) ultimatelyhave"xs ! (j - 1) ≠0""xs ! (j - 1) ≠1" using Suc.prems has2_def by auto thenhave"?zs ! (j - 1) ≠0""?zs ! (j - 1) ≠1" by (simp_all add: ‹0 < j›) moreoverhave"?zs ! (j - 1) < ♯" using `symbols_lt 5 ?zs` `0 < j ` j(1) len by simp moreoverhave"?zs ! (j - 1) ≥0" using `proper_symbols ?zs` len ‹0 < j›by (metis One_nat_def Suc_1 Suc_leI diff_less zero_less_one) ultimatelyhave"?zs ! (j - 1) = ∣" by simp thenshow"last ?zs = ∣" using len by (metis last_conv_nth neq_Nil) qed ultimatelyshow"numlist_wf ?zs" using numlist_wf_iff by simp qed
let ?ts = "take (Suc j) xs" have"?ts = ?zs @ [♯]" using j by (metis take_Suc_conv_app_nth) thenhave"numlistlist_wf ?ts" using numlistlist_wf_numlist_wf `numlist_wf ?zs` by simp moreoverhave"xs = ?ts @ ?ys" by simp ultimatelyshow"numlistlist_wf xs" using wf_ys numlistlist_wf_append by fastforce qed
lemma numlistlist_not_has2: assumes"i < length (numlistlist nss) - 1"and"numlistlist nss ! i = 0" shows"numlistlist nss ! (Suc i) ≠∣" using assms proof (induction nss arbitrary: i) case Nil thenshow ?case by (simp add: numlistlist_Nil) next case (Cons ns nss) show"numlistlist (ns # nss) ! (Suc i) ≠∣" proof (cases "i < length (numlistlist [ns])") case True have"numlistlist (ns # nss) ! i = (numlistlist [ns] @ numlistlist nss) ! i" using numlistlist_def by simp thenhave"numlistlist (ns # nss) ! i = numlistlist [ns] ! i" using True by (simp add: nth_append) thenhave"numlistlist (ns # nss) ! i = (numlist ns @ [♯]) ! i" using numlistlist_def by simp moreoverhave"numlistlist (ns # nss) ! i = 0" using Cons by simp ultimatelyhave"(numlist ns @ [♯]) ! i = 0" by simp moreoverhave"(numlist ns @ [♯]) ! (length (numlist ns @ [♯]) - 1) = ♯" by simp ultimatelyhave"i ≠ length (numlist ns @ [♯]) - 1" by auto thenhave *: "i ≠ length (numlistlist [ns]) - 1" using numlistlist_def by simp thenhave **: "i < length (numlistlist [ns]) - 1" using True by simp thenhave ***: "i < length (numlist ns)" using numlistlist_def by simp thenhave"ns ≠ []" using numlist_Nil by auto thenhave"last (numlist ns) = ∣" by (metis last_numlist_4 numlist_Nil numlist_inj)
have3: "numlist ns ! j = numlistlist (ns # nss) ! j"if"j < length (numlist ns)"forj proof - have j: "j < length (numlistlist [ns])" using that numlistlist_def by simp have"numlistlist (ns # nss) ! j = (numlistlist [ns] @ numlistlist nss) ! j" using numlistlist_def by simp thenhave"numlistlist (ns # nss) ! j = numlistlist [ns] ! j" using j by (simp add: nth_append) thenhave"numlistlist (ns # nss) ! j = (numlist ns @ [♯]) ! j" using numlistlist_def by simp thenshow ?thesis by (simp add: nth_append that) qed have4: "numlistlist (ns # nss) ! (length (numlist ns)) = ♯" by (simp add: numlistlist_def)
show ?thesis proof (cases "i = length (numlist ns) - 1") case True thenshow ?thesis using34 *** by (metis Suc_le_D Suc_le_eq diff_Suc_1 eval_nat_numeral(3) n_not_Suc_n) next case False thenhave"i < length (numlist ns) - 1" using *** by simp thenshow ?thesis using numlist_not_has2 *** 3‹ns ≠ []› by (metis Cons.prems(2) Suc_diff_1 length_greater_0_conv not_less_eq numlist_Nil numlist_inj) qed next case False thenhave"i ≥ length (numlistlist [ns])" by simp let ?i = "i - length (numlistlist [ns])" have"numlistlist (ns # nss) ! i = (numlistlist [ns] @ numlistlist nss) ! i" using numlistlist_def by simp thenhave"numlistlist (ns # nss) ! i = numlistlist nss ! ?i" using False by (simp add: nth_append) thenhave"numlistlist nss ! ?i = 0" using Cons by simp moreoverhave"?i < length (numlistlist nss) - 1" proof - have"length (numlistlist (ns # nss)) = length (numlistlist [ns]) + length (numlistlist nss)" using numlistlist_def by simp thenshow ?thesis using False Cons by simp qed ultimatelyhave"numlistlist nss ! Suc ?i ≠∣" using Cons by simp moreoverhave"numlistlist (ns # nss) ! Suc i = numlistlist nss ! Suc ?i" using False numlistlist_append by (smt (verit, del_insts) Suc_diff_Suc Suc_lessD append_Cons append_Nil diff_Suc_Suc not_less_eq nth_append) ultimatelyshow ?thesis by simp qed qed
lemma numlistlist_not_has2': assumes"i < length (numlistlist nss) - 1"and"numlistlist nss ! i = 0∨ numlistlist nss ! i = 1" shows"numlistlist nss ! (Suc i) ≠♯" using assms proof (induction nss arbitrary: i) case Nil thenshow ?case by (simp add: numlistlist_Nil) next case (Cons ns nss) show"numlistlist (ns # nss) ! (Suc i) ≠♯" proof (cases "i < length (numlistlist [ns])") case True have"numlistlist (ns # nss) ! i = (numlistlist [ns] @ numlistlist nss) ! i" using numlistlist_def by simp thenhave"numlistlist (ns # nss) ! i = numlistlist [ns] ! i" using True by (simp add: nth_append) thenhave"numlistlist (ns # nss) ! i = (numlist ns @ [♯]) ! i" using numlistlist_def by simp moreoverhave"numlistlist (ns # nss) ! i = 0∨ numlistlist (ns # nss) ! i = 1" using Cons by simp ultimatelyhave"(numlist ns @ [♯]) ! i = 0∨ (numlist ns @ [♯]) ! i = 1" by simp moreoverhave"(numlist ns @ [♯]) ! (length (numlist ns @ [♯]) - 1) = ♯" by simp ultimatelyhave"i ≠ length (numlist ns @ [♯]) - 1" by auto thenhave"i ≠ length (numlistlist [ns]) - 1" using numlistlist_def by simp thenhave"i < length (numlistlist [ns]) - 1" using True by simp thenhave *: "i < length (numlist ns)" using numlistlist_def by simp thenhave"ns ≠ []" using numlist_Nil by auto thenhave"last (numlist ns) = ∣" by (metis last_numlist_4 numlist_Nil numlist_inj)
have **: "numlist ns ! j = numlistlist (ns # nss) ! j"if"j < length (numlist ns)"for j proof - have j: "j < length (numlistlist [ns])" using that numlistlist_def by simp have"numlistlist (ns # nss) ! j = (numlistlist [ns] @ numlistlist nss) ! j" using numlistlist_def by simp thenhave"numlistlist (ns # nss) ! j = numlistlist [ns] ! j" using j by (simp add: nth_append) thenhave"numlistlist (ns # nss) ! j = (numlist ns @ [♯]) ! j" using numlistlist_def by simp thenshow ?thesis by (simp add: nth_append that) qed
show ?thesis proof (cases "i = length (numlist ns) - 1") case True thenshow ?thesis using‹last (numlist ns) = ∣›‹ns ≠ []› Cons.prems(2) * ** numlist_Nil numlist_inj by (metis last_conv_nth num.simps(8) numeral_eq_iff semiring_norm(83) verit_eq_simplify(8)) next case False thenhave"i < length (numlist ns) - 1" using * by simp thenshow ?thesis using * ** symbols_lt_numlist numlist_not_has2 by (metis Suc_lessI diff_Suc_1 less_irrefl_nat) qed next case False thenhave"i ≥ length (numlistlist [ns])" by simp let ?i = "i - length (numlistlist [ns])" have"numlistlist (ns # nss) ! i = (numlistlist [ns] @ numlistlist nss) ! i" using numlistlist_def by simp thenhave"numlistlist (ns # nss) ! i = numlistlist nss ! ?i" using False by (simp add: nth_append) thenhave"numlistlist nss ! ?i = 0∨ numlistlist nss ! ?i = 1" using Cons by simp moreoverhave"?i < length (numlistlist nss) - 1" proof - have"length (numlistlist (ns # nss)) = length (numlistlist [ns]) + length (numlistlist nss)" using numlistlist_def by simp thenshow ?thesis using False Cons by simp qed ultimatelyhave"numlistlist nss ! Suc ?i ≠♯" using Cons by simp moreoverhave"numlistlist (ns # nss) ! Suc i = numlistlist nss ! Suc ?i" using False numlistlist_append by (smt (verit, del_insts) Suc_diff_Suc Suc_lessD append_Cons append_Nil diff_Suc_Suc not_less_eq nth_append) ultimatelyshow ?thesis by simp qed qed
lemma last_numlistlist_5: "numlistlist nss ≠ [] ==> last (numlistlist nss) = ♯" using numlistlist_def by (induction nss) simp_all
lemma numlistlist_wf_has2': assumes"numlistlist_wf xs" shows"proper_symbols_lt 6 xs ∧ (xs ≠ [] ⟶ last xs = ♯) ∧¬ has2 xs 0∣∧¬ has2 xs 0♯∧¬ has2 xs 1♯" proof - obtain nss where nss: "numlistlist nss = xs" using numlistlist_wf_def assms by auto have"proper_symbols xs" using nss proper_symbols_numlistlist by auto moreoverhave"symbols_lt 6 xs" using nss symbols_lt_numlistlist by auto moreoverhave"xs ≠ [] ⟶ last xs = ♯" using nss last_numlistlist_5 by auto moreoverhave"¬ has2 xs 0∣"and"¬ has2 xs 0♯"and"¬ has2 xs 1♯" using numlistlist_not_has2 numlistlist_not_has2' has2_def nss by auto ultimatelyshow ?thesis by simp qed
subsection‹A Turing machine to check for subsequences of length two›
text‹
order to implement the well-formedness criteria we need to be able to check a
sequence for subsequences of length two. The next Turing machine has
parameters $y$ and $z$ and checks whether the sequence @{term "[y, z]"}
on tape $j_1$. It writes to tape $j_2$ the number~0 or~1 if the sequence
present or not, respectively. ›
definition tm_not_has2 :: "symbol ==> symbol ==> tapeidx ==> tapeidx ==> machine"where "tm_not_has2 y z j1 j2 ≡ tm_set j2 [0, 0] ;; WHILE [] ; λrs. rs ! j1 ≠◻ DO IF λrs. rs ! j2 = 1∧ rs ! j1 = z THEN tm_right j2 ;; tm_write j2 1 ;; tm_left j2 ELSE [] ENDIF ;; tm_trans2 j1 j2 (λh. if h = y then 1 else 0) ;; tm_right j1 DONE ;; tm_right j2 ;; IF λrs. rs ! j2 = 1 THEN tm_set j2 (canrepr 1) ELSE tm_set j2 (canrepr 0) ENDIF ;; tm_cr j1 ;; tm_not j2"
lemma tm_not_has2_tm: assumes"k ≥ 2"and"G ≥ 4"and"0 < j2"and"j1 < k"and"j2 < k" shows"turing_machine k G (tm_not_has2 y z j1 j2)" proof - have"symbols_lt G [0, 0]" using assms(2) by (simp add: nth_Cons') moreoverhave"symbols_lt G (canrepr 0)" using assms(2) by simp moreoverhave"symbols_lt G (canrepr 1)" using assms(2) canrepr_1 by simp ultimatelyshow ?thesis unfolding tm_not_has2_def using assms tm_right_tm tm_write_tm tm_left_tm tm_cr_tm Nil_tm tm_trans2_tm tm_set_tm
turing_machine_loop_turing_machine turing_machine_branch_turing_machine tm_not_tm by simp qed
locale turing_machine_has2 = fixes y z :: symbol and j1 j2 :: tapeidx begin
lemma tm1: "transforms tm1 tps0 14 tps1" unfolding tm1_def proof (tform tps: tps0 tps1_def jk) show"∀i<length [0, 0]. Suc 0 < [0, 0] ! i" by (simp add: nth_Cons') show"tps1 = tps0[j2 := (⌊[0, 0]⌋, 1)]" using tps1_def tps0 jk by (metis list_update_id) qed
abbreviation has_at :: "nat ==> bool"where "has_at i ≡ xs ! i = y ∧ xs ! Suc i = z"
definition tpsL :: "nat ==> tape list"where "tpsL t ≡ tps0 [j1 := (⌊xs⌋, Suc t), j2 := (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t - 1. has_at i then 1 else 0]⌋, 1)]"
lemma tpsL_eq_tps1: "tpsL 0 = tps1" unfolding tps1_def tpsL_def using yz jk by simp
lemma tm1' [transforms_intros]: "transforms tm1 tps0 14 (tpsL 0)" using tm1 tpsL_eq_tps1 by simp
definition tpsT1 :: "nat ==> tape list"where "tpsT1 t ≡ tps0 [j1 := (⌊xs⌋, Suc t), j2 := (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t - 1. has_at i then 1 else 0]⌋, 2)]"
definition tpsT2 :: "nat ==> tape list"where "tpsT2 t ≡ tps0 [j1 := (⌊xs⌋, Suc t), j2 := (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 2)]"
definition tpsT3 :: "nat ==> tape list"where "tpsT3 t ≡ tps0 [j1 := (⌊xs⌋, Suc t), j2 := (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 1)]"
lemma contents_1_update: "(⌊[a, b]⌋, 1) |:=| v = (⌊[v, b]⌋, 1)"for a b v :: symbol using contents_def by auto
lemma contents_2_update: "(⌊[a, b]⌋, 2) |:=| v = (⌊[a, v]⌋, 2)"for a b v :: symbol using contents_def by auto
context fixes t :: nat assumes then_branch: "⌊xs⌋ t = y""xs ! t = z" begin
lemma tmT1 [transforms_intros]: "transforms tmT1 (tpsL t) 1 (tpsT1 t)" unfolding tmT1_def proof (tform tps: tpsL_def tpsT1_def jk) have"tpsL t ! j2 |+| 1 = (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t - 1. has_at i then 1 else 0]⌋, 2)" using jk tpsL_def by simp moreoverhave"tpsT1 t = (tpsL t)[j2 := (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t - 1. has_at i then 1 else 0]⌋, 2)]" unfolding tpsT1_def tpsL_def by simp ultimatelyshow"tpsT1 t = (tpsL t)[j2 := tpsL t ! j2 |+| 1]" by presburger qed
lemma tmT2 [transforms_intros]: "transforms tmT2 (tpsL t) 2 (tpsT2 t)" unfolding tmT2_def proof (tform tps: tpsT1_def tpsT2_def jk) have1: "tpsT1 t ! j2 = (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t - 1. has_at i then 1 else 0]⌋, 2)" using tpsT1_def jk by simp have2: "tpsT1 t ! j2 |:=| 1 = (⌊[if ⌊xs⌋ t = y then 1 else 0, 1]⌋, 2)" using tpsT1_def jk contents_2_update by simp have3: "tpsT2 t ! j2 = (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 2)" using tpsT2_def jk by simp
have"∃i<t. has_at i" proof - have"t > 0" using then_branch(1) yz(1) by (metis contents_at_0 gr0I less_numeral_extra(4)) thenhave"y = xs ! (t - 1)" using then_branch(1) by (metis contents_def nat_neq_iff not_one_less_zero yz(1)) moreoverhave"z = xs ! t" using then_branch(2) by simp ultimatelyhave"has_at (t - 1)" using `0 < t` by simp thenshow"∃i<t. has_at i" using `0 < t` by (metis Suc_pred' lessI) qed thenhave"(if ∃i<t. has_at i then 1 else 0) = 1" by simp thenhave"tpsT1 t ! j2 |:=| 1 = (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 2)" using23by (smt (verit, ccfv_threshold)) thenshow"tpsT2 t = (tpsT1 t)[j2 := tpsT1 t ! j2 |:=| 1]" unfolding tpsT2_def tpsT1_def using jk by simp qed
lemma tmL1 [transforms_intros]: assumes"ttt = 5"and"t < length xs" shows"transforms tmL1 (tpsL t) ttt (tpsT3 t)" unfolding tmL1_def proof (tform tps: assms(1) tpsL_def tpsT3_def jk) have"read (tpsL t) ! j1 = tpsL t :.: j1" using jk tpsL_def tapes_at_read'[of j1 "tpsL t"] by simp thenhave1: "read (tpsL t) ! j1 = xs ! t" using jk tpsL_def assms(2) by simp thenshow"read (tpsL t) ! j2 = 1∧ read (tpsL t) ! j1 = z ==> xs ! t = z" by simp have"read (tpsL t) ! j2 = tpsL t :.: j2" using jk tpsL_def tapes_at_read'[of j2 "tpsL t"] by simp thenhave2: "read (tpsL t) ! j2 = (if ⌊xs⌋ t = y then 1 else 0)" using jk tpsL_def by simp thenshow"read (tpsL t) ! j2 = 1∧ read (tpsL t) ! j1 = z ==>⌊xs⌋ t = y" by presburger show"tpsT3 t = tpsL t"if"¬ (read (tpsL t) ! j2 = 1∧ read (tpsL t) ! j1 = z)" proof - have"(∃i<t. has_at i) = (∃i<t - 1. has_at i)" proof (cases "t = 0") case True thenshow ?thesis by simp next case False have"¬ ((if ⌊xs⌋ t = y then 0::symbol else 1) = 0 ∧ xs ! t = z)" using12 that by simp thenhave"¬ (⌊xs⌋ t = y ∧ xs ! t = z)" by auto thenhave"¬ (has_at (t - 1))" using False Suc_pred' assms(2) contents_inbounds less_imp_le_nat by simp moreoverhave"(∃i<t. has_at i) = (∃i<t - Suc 0. has_at i) ∨ has_at (t - 1)" using False by (metis One_nat_def add_diff_inverse_nat less_Suc_eq less_one plus_1_eq_Suc) ultimatelyshow ?thesis by auto qed thenhave eq: "(if ∃i<t - 1. has_at i then 1 else 0) = (if ∃i<t. has_at i then 1 else0)" by simp show ?thesis unfolding tpsT3_def tpsL_def by (simp only: eq) qed qed
definition tpsL2 :: "nat ==> tape list"where "tpsL2 t ≡ tps0 [j1 := (⌊xs⌋, Suc t), j2 := (⌊[if ⌊xs⌋ (Suc t) = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 1)]"
lemma tmL2 [transforms_intros]: assumes"ttt = 6"and"t < length xs" shows"transforms tmL2 (tpsL t) ttt (tpsL2 t)" unfolding tmL2_def proof (tform tps: assms tpsL_def tpsT3_def jk) have"tpsT3 t ! j2 = (⌊[if ⌊xs⌋ t = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 1)" using jk tpsT3_def by simp thenhave"tpsT3 t ! j2 |:=| (if tpsT3 t :.: j1 = y then 1 else 0) = (⌊[if tpsT3 t :.: j1 = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 1)" using contents_1_update by simp moreoverhave"tpsT3 t :.: j1 = ⌊xs⌋ (Suc t)" using assms(2) tpsT3_def jk by simp ultimatelyhave"tpsT3 t ! j2 |:=| (if tpsT3 t :.: j1 = y then 1 else 0) = (⌊[if ⌊xs⌋ (Suc t) = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 1)" by auto moreoverhave"tpsL2 t = (tpsT3 t)[j2 := (⌊[if ⌊xs⌋ (Suc t) = y then 1 else 0, if ∃i<t. has_at i then 1 else 0]⌋, 1)]" using tpsL2_def tpsT3_def by simp ultimatelyshow"tpsL2 t = (tpsT3 t)[j2 := tpsT3 t ! j2 |:=| (if tpsT3 t :.: j1 = y then 1 else 0)]" by presburger qed
lemma tmL3 [transforms_intros]: assumes"ttt = 7"and"t < length xs" shows"transforms tmL3 (tpsL t) ttt (tpsL (Suc t))" unfolding tmL3_def proof (tform tps: assms tpsL_def tpsL2_def jk) have"tpsL2 t ! j1 = (⌊xs⌋, Suc t)" using tpsL2_def jk by simp thenshow"tpsL (Suc t) = (tpsL2 t)[j1 := tpsL2 t ! j1 |+| 1]" using tpsL2_def tpsL_def jk by (simp add: list_update_swap) qed
lemma tmL [transforms_intros]: assumes"ttt = 9 * length xs + 1" shows"transforms tmL (tpsL 0) ttt (tpsL (length xs))" unfolding tmL_def proof (tform time: assms) have"read (tpsL t) ! j1 = tpsL t :.: j1"for t using tpsL_def tapes_at_read' jk by (metis (no_types, lifting) length_list_update) thenhave"read (tpsL t) ! j1 = ⌊xs⌋ (Suc t)"for t using tpsL_def jk by simp thenshow"∧t. t < length xs ==> read (tpsL t) ! j1 ≠◻"and"¬ read (tpsL (length xs)) ! j1 ≠◻" using xs by auto qed
lemma tm6: assumes"ttt = 10 * length xs + 41" shows"transforms tm6 tps0 ttt tps6" unfolding tm6_def proof (tform tps: assms tps5'_def jk) have"tps5'[j2 := (⌊(if has2 xs y z then 1::nat else 0) ≠ 1⌋B, 1)] = tps5'[j2 := (⌊¬ has2 xs y z⌋B, 1)]" by simp alsohave"... = tps0[j2 := (⌊¬ has2 xs y z⌋B, 1)]" using tps5'_defby simp alsohave"... = tps6" using tps6_def by simp finallyshow"tps6 = tps5' [j2 := (⌊(if has2 xs y z then 1::nat else 0) ≠ 1⌋B, 1)]" by simp qed
end(* context *)
end(* locale *)
lemma transforms_tm_not_has2I [transforms_intros]: fixes y z :: symbol and j1 j2 :: tapeidx fixes tps tps' :: "tape list"and xs :: "symbol list"and ttt k :: nat assumes"j1 < k""j2 < k""j1 ≠ j2""0 < j2""length tps = k""y > 1""z > 1" and"proper_symbols xs" assumes "tps ! j1 = (⌊xs⌋, 1)" "tps ! j2 = (⌊[]⌋, 1)" assumes"ttt = 10 * length xs + 41" assumes"tps' = tps [j2 := (⌊¬ has2 xs y z⌋B, 1)]" shows"transforms (tm_not_has2 y z j1 j2) tps ttt tps'" proof - interpret loc: turing_machine_has2 y z j1 j2 . show ?thesis using loc.tps6_def loc.tm6 loc.tm6_eq_tm_not_has2 assms by metis qed
subsection‹Checking well-formedness for lists›
text‹
next Turing machine checks all conditions from the criterion in lemma @{thm
source] numlist_wf_iff} one after another for the symbols on tape $j_1$ and
to tape $j_2$ either the number~1 or~0 depending on whether all
were met. It assumes tape $j_2$ is initialized with~0. ›
subsection‹Checking well-formedness for lists of lists›
text‹
next Turing machine checks all conditions from the criterion in lemma @{thm
source] numlistlist_wf_iff} one after another for the symbols on tape $j_1$ and
to tape $j_2$ either the number~1 or~0 depending on whether all
were met. It assumes tape $j_2$ is initialized with~0. ›
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.