diff -r a8785fa80278 -r 2f765afc1f7e thys/uncomputable.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thys/uncomputable.thy Wed Jan 16 10:12:43 2013 +0000 @@ -0,0 +1,1451 @@ +(* Title: Turing machine's definition and its charater + Author: XuJian + Maintainer: Xujian +*) + +header {* Undeciablity of the {\em Halting problem} *} + +theory uncomputable +imports Main turing_basic +begin + +text {* + The {\em Copying} TM, which duplicates its input. +*} + +definition tcopy_init :: "instr list" +where +"tcopy_init \ [(W0, 0), (R, 2), (R, 3), (R, 2), + (W1, 3), (L, 4), (L, 4), (L, 0)]" + +fun inv_init1 :: "nat \ tape \ bool" + where + "inv_init1 x (l, r) = (l = [] \ r = Oc\x )" + +fun inv_init2 :: "nat \ tape \ bool" + where + "inv_init2 x (l, r) = (\ i j. i > 0 \ i + j = x \ l = Oc\i \ r = Oc\j)" + +fun inv_init3 :: "nat \ tape \ bool" + where + "inv_init3 x (l, r) = (x > 0 \ l = Bk # Oc\x \ tl r = [])" + +fun inv_init4 :: "nat \ tape \ bool" + where + "inv_init4 x (l, r) = (x > 0 \ ((l = Oc\x \ r = [Bk, Oc]) \ (l = Oc\(x - 1) \ r = [Oc, Bk, Oc])))" + +fun inv_init0 :: "nat \ tape \ bool" + where + "inv_init0 x (l, r) = ((x > Suc 0 \ l = Oc\(x - 2) \ r = [Oc, Oc, Bk, Oc]) \ + (x = 1 \ l = [] \ r = [Bk, Oc, Bk, Oc]))" + +fun inv_init :: "nat \ config \ bool" + where + "inv_init x (s, l, r) = ( + if s = 0 then inv_init0 x (l, r) + else if s = Suc 0 then inv_init1 x (l, r) + else if s = 2 then inv_init2 x (l, r) + else if s = 3 then inv_init3 x (l, r) + else if s = 4 then inv_init4 x (l, r) + else False)" + +declare inv_init.simps[simp del] + +lemma numeral_4_eq_4: "4 = Suc 3" +by arith + +lemma [elim]: "\0 < i; 0 < j\ \ + \ia>0. ia + j - Suc 0 = i + j \ Oc # Oc \ i = Oc \ ia" +apply(rule_tac x = "Suc i" in exI, simp) +done + +lemma inv_init_step: + "\inv_init x cf; x > 0\ + \ inv_init x (step cf (tcopy_init, 0))" +apply(case_tac cf) +apply(auto simp: inv_init.simps step.simps tcopy_init_def numeral_2_eq_2 + numeral_3_eq_3 numeral_4_eq_4 split: if_splits) +apply(case_tac "hd c", auto simp: inv_init.simps) +apply(case_tac c, simp_all) +done + +lemma inv_init_steps: + "\inv_init x (s, l, r); x > 0\ + \ inv_init x (steps (s, l, r) (tcopy_init, 0) stp)" +apply(induct stp, simp add: steps.simps) +apply(auto simp: step_red) +apply(rule_tac inv_init_step, simp_all) +done + +fun init_state :: "config \ nat" + where + "init_state (s, l, r) = (if s = 0 then 0 + else 5 - s)" + +fun init_step :: "config \ nat" + where + "init_step (s, l, r) = (if s = 2 then length r + else if s = 3 then if r = [] \ r = [Bk] then Suc 0 else 0 + else if s = 4 then length l + else 0)" + +fun init_measure :: "config \ nat \ nat" + where + "init_measure c = + (init_state c, init_step c)" + + +definition lex_pair :: "((nat \ nat) \ nat \ nat) set" + where + "lex_pair \ less_than <*lex*> less_than" + +definition init_LE :: "(config \ config) set" + where + "init_LE \ (inv_image lex_pair init_measure)" + +lemma [simp]: "\tl r = []; r \ []; r \ [Bk]\ \ r = [Oc]" +apply(case_tac r, auto, case_tac a, auto) +done + +lemma wf_init_le: "wf init_LE" +by(auto intro:wf_inv_image simp:init_LE_def lex_pair_def) + +lemma init_halt: + "x > 0 \ \ stp. is_final (steps (Suc 0, [], Oc\x) (tcopy_init, 0) stp)" +proof(rule_tac LE = init_LE in halt_lemma) + show "wf init_LE" by(simp add: wf_init_le) +next + assume h: "0 < x" + show "\n. \ is_final (steps (Suc 0, [], Oc \ x) (tcopy_init, 0) n) \ + (steps (Suc 0, [], Oc \ x) (tcopy_init, 0) (Suc n), + steps (Suc 0, [], Oc \ x) (tcopy_init, 0) n) \ init_LE" + proof(rule_tac allI, rule_tac impI) + fix n + assume a: "\ is_final (steps (Suc 0, [], Oc \ x) (tcopy_init, 0) n)" + have b: "inv_init x (steps (Suc 0, [], Oc \ x) (tcopy_init, 0) n)" + apply(rule_tac inv_init_steps) + apply(simp_all add: inv_init.simps h) + done + obtain s l r where c: "(steps (Suc 0, [], Oc \ x) (tcopy_init, 0) n) = (s, l, r)" + apply(case_tac "steps (Suc 0, [], Oc \ x) (tcopy_init, 0) n", auto) + done + moreover hence "inv_init x (s, l, r)" + using c b by simp + ultimately show "(steps (Suc 0, [], Oc \ x) (tcopy_init, 0) (Suc n), + steps (Suc 0, [], Oc \ x) (tcopy_init, 0) n) \ init_LE" + using a + proof(simp) + assume "inv_init x (s, l, r)" "0 < s" + thus "(step (s, l, r) (tcopy_init, 0), s, l, r) \ init_LE" + apply(auto simp: inv_init.simps init_LE_def lex_pair_def step.simps tcopy_init_def numeral_2_eq_2 + numeral_3_eq_3 numeral_4_eq_4 split: if_splits) + apply(case_tac r, auto, case_tac a, auto) + done + qed + qed +qed + +lemma init_correct: + "x > 0 \ + {inv_init1 x} (tcopy_init, 0) {inv_init0 x}" +proof(rule_tac HoareI) + fix l r + assume h: "0 < x" + "inv_init1 x (l, r)" + hence "\ stp. is_final (steps (Suc 0, [], Oc\x) (tcopy_init, 0) stp)" + by(erule_tac init_halt) + then obtain stp where "is_final (steps (Suc 0, [], Oc\x) (tcopy_init, 0) stp)" .. + moreover have "inv_init x (steps (Suc 0, [], Oc\x) (tcopy_init, 0) stp)" + apply(rule_tac inv_init_steps) + using h by(simp_all add: inv_init.simps) + ultimately show + "\n. is_final (steps (1, l, r) (tcopy_init, 0) n) \ + inv_init0 x holds_for steps (1, l, r) (tcopy_init, 0) n" + using h + apply(rule_tac x = stp in exI) + apply(case_tac "(steps (Suc 0, [], Oc \ x) (tcopy_init, 0) stp)", simp add: inv_init.simps) + done +qed + +definition tcopy_loop :: "instr list" +where +"tcopy_loop \ [(R, 0), (R, 2), (R, 3), (W0, 2), + (R, 3), (R, 4), (W1, 5), (R, 4), + (L, 6), (L, 5), (L, 6), (L, 1)]" + +fun inv_loop1_loop :: "nat \ tape \ bool" + where + "inv_loop1_loop x (l, r) = + (\ i j. i + j + 1 = x \ l = Oc\i \ r = Oc # Oc # Bk\j @ Oc\j \ j > 0)" + +fun inv_loop1_exit :: "nat \ tape \ bool" + where + "inv_loop1_exit x (l, r) = + (l = [] \ r = Bk # Oc # Bk\x @ Oc\x \ x > 0 )" + +fun inv_loop1 :: "nat \ tape \ bool" + where + "inv_loop1 x (l, r) = (inv_loop1_loop x (l, r) \ inv_loop1_exit x (l, r))" + +fun inv_loop2 :: "nat \ tape \ bool" + where + "inv_loop2 x (l, r) = + (\ i j any. i + j = x \ x > 0 \ i > 0 \ j > 0 \ l = Oc\i \ r = any#Bk\j@Oc\j)" + +fun inv_loop3 :: "nat \ tape \ bool" + where + "inv_loop3 x (l, r) = + (\ i j k t. i + j = x \ i > 0 \ j > 0 \ k + t = Suc j \ l = Bk\k@Oc\i \ r = Bk\t@Oc\j)" + +fun inv_loop4 :: "nat \ tape \ bool" + where + "inv_loop4 x (l, r) = + (\ i j k t. i + j = x \ i > 0 \ j > 0 \ k + t = j \ l = Oc\k @ Bk\(Suc j)@Oc\i \ r = Oc\t)" + +fun inv_loop5_loop :: "nat \ tape \ bool" +where + "inv_loop5_loop x (l, r) = + (\ i j k t. i + j = Suc x \ i > 0 \ j > 0 \ k + t = j \ t > 0 \ l = Oc\k@Bk\j@Oc\i \ r = Oc\t)" + +fun inv_loop5_exit :: "nat \ tape \ bool" + where + "inv_loop5_exit x (l, r) = (\ i j. i + j = Suc x \ i > 0 \ j > 0 \ l = Bk\(j - 1)@Oc\i \ r = Bk # Oc\j)" + +fun inv_loop5 :: "nat \ tape \ bool" + where + "inv_loop5 x (l, r) = (inv_loop5_loop x (l, r) \ + inv_loop5_exit x (l, r))" + +fun inv_loop6_loop :: "nat \ tape \ bool" + where + "inv_loop6_loop x (l, r) = + (\ i j k t. i + j = Suc x \ i > 0 \ k + t + 1 = j \ l = Bk\k @ Oc\i \ r = Bk\(Suc t) @ Oc\j)" + +fun inv_loop6_exit :: "nat \ tape \ bool" + where + "inv_loop6_exit x (l, r) = + (\ i j. i + j = x \ j > 0 \ l = Oc\i \ r = Oc # Bk\j @ Oc\j)" + +fun inv_loop6 :: "nat \ tape \ bool" + where + "inv_loop6 x (l, r) = (inv_loop6_loop x (l, r) \ inv_loop6_exit x (l, r))" + +fun inv_loop0 :: "nat \ tape \ bool" + where + "inv_loop0 x (l, r) = + (l = [Bk] \ r = Oc # Bk\x @ Oc\x \ x > 0 )" + +fun inv_loop :: "nat \ config \ bool" + where + "inv_loop x (s, l, r) = + (if s = 0 then inv_loop0 x (l, r) + else if s = 1 then inv_loop1 x (l, r) + else if s = 2 then inv_loop2 x (l, r) + else if s = 3 then inv_loop3 x (l, r) + else if s = 4 then inv_loop4 x (l, r) + else if s = 5 then inv_loop5 x (l, r) + else if s = 6 then inv_loop6 x (l, r) + else False)" + +declare inv_loop.simps[simp del] inv_loop1.simps[simp del] + inv_loop2.simps[simp del] inv_loop3.simps[simp del] + inv_loop4.simps[simp del] inv_loop5.simps[simp del] + inv_loop6.simps[simp del] +lemma [elim]: "Bk # list = Oc \ t \ RR" +apply(case_tac t, auto) +done + +lemma numeral_5_eq_5: "5 = Suc 4" by arith + +lemma numeral_6_eq_6: "6 = Suc (Suc 4)" by arith + +lemma [simp]: "inv_loop1 x (b, []) = False" +by(simp add: inv_loop1.simps) + +lemma [elim]: "\0 < x; inv_loop2 x (b, [])\ \ inv_loop3 x (Bk # b, [])" +apply(auto simp: inv_loop2.simps inv_loop3.simps) +done + +lemma [elim]: "\0 < x; inv_loop3 x (b, [])\ \ inv_loop3 x (Bk # b, [])" +apply(auto simp: inv_loop3.simps) +done + +lemma [elim]: "\0 < x; inv_loop4 x (b, [])\ \ inv_loop5 x (b, [Oc])" +apply(auto simp: inv_loop4.simps inv_loop5.simps) +apply(rule_tac [!] x = i in exI, + rule_tac [!] x = "Suc j" in exI, simp_all) +done + +lemma [elim]: "\0 < x; inv_loop5 x ([], [])\ \ RR" +apply(auto simp: inv_loop4.simps inv_loop5.simps) +done + +lemma [elim]: "\0 < x; inv_loop5 x (b, []); b \ []\ \ RR" +apply(auto simp: inv_loop4.simps inv_loop5.simps) +done + +lemma [elim]: "inv_loop6 x ([], []) \ RR" +apply(auto simp: inv_loop6.simps) +done + +thm inv_loop6_exit.simps +lemma [elim]: "inv_loop6 x (b, []) \ RR" +apply(auto simp: inv_loop6.simps) +done + +lemma [elim]: "\0 < x; inv_loop1 x (b, Bk # list)\ \ b = []" +apply(auto simp: inv_loop1.simps) +done + +lemma [elim]: "\0 < x; inv_loop1 x (b, Bk # list)\ \ list = Oc # Bk \ x @ Oc \ x" +apply(auto simp: inv_loop1.simps) +done + +lemma [elim]: "\0 < x; inv_loop2 x (b, Bk # list)\ \ inv_loop3 x (Bk # b, list)" +apply(auto simp: inv_loop2.simps inv_loop3.simps) +apply(rule_tac [!] x = i in exI, rule_tac [!] x = j in exI, simp_all) +done + +lemma [elim]: "Bk # list = Oc \ j \ RR" +apply(case_tac j, simp_all) +done + +lemma [elim]: "\0 < x; inv_loop3 x (b, Bk # list)\ \ inv_loop3 x (Bk # b, list)" +apply(auto simp: inv_loop3.simps) +apply(rule_tac [!] x = i in exI, + rule_tac [!] x = j in exI, simp_all) +apply(case_tac [!] t, auto) +done + +lemma [elim]: "\0 < x; inv_loop4 x (b, Bk # list)\ \ inv_loop5 x (b, Oc # list)" +apply(auto simp: inv_loop4.simps inv_loop5.simps) +done + +lemma [elim]: "\0 < x; inv_loop5 x ([], Bk # list)\ \ inv_loop6 x ([], Bk # Bk # list)" +apply(auto simp: inv_loop6.simps inv_loop5.simps) +done + +lemma [simp]: "inv_loop5_loop x (b, Bk # list) = False" +apply(auto simp: inv_loop5_loop.simps) +done + +lemma [simp]: "inv_loop6_exit x (b, Bk # list) = False" +apply(auto simp: inv_loop6.simps) +done + +declare inv_loop5_loop.simps[simp del] inv_loop5_exit.simps[simp del] + inv_loop6_loop.simps[simp del] inv_loop6_exit.simps[simp del] + +lemma [elim]:"\0 < x; inv_loop5_exit x (b, Bk # list); b \ []; hd b = Bk\ + \ inv_loop6_loop x (tl b, Bk # Bk # list)" +apply(simp only: inv_loop5_exit.simps inv_loop6_loop.simps ) +apply(erule_tac exE)+ +apply(rule_tac x = i in exI, + rule_tac x = j in exI, + rule_tac x = "j - Suc (Suc 0)" in exI, + rule_tac x = "Suc 0" in exI, auto) +apply(case_tac [!] j, simp_all) +apply(case_tac [!] nat, simp_all) +done + +lemma [simp]: "inv_loop6_loop x (b, Oc # Bk # list) = False" +apply(auto simp: inv_loop6_loop.simps) +done + +lemma [elim]: "\x > 0; inv_loop5_exit x (b, Bk # list); b \ []; hd b = Oc\ \ + inv_loop6_exit x (tl b, Oc # Bk # list)" +apply(simp only: inv_loop5_exit.simps inv_loop6_exit.simps) +apply(erule_tac exE)+ +apply(rule_tac x = "x - 1" in exI, rule_tac x = 1 in exI, simp) +apply(case_tac j, auto) +apply(case_tac [!] nat, auto) +done + +lemma [elim]: "\0 < x; inv_loop5 x (b, Bk # list); b \ []\ \ inv_loop6 x (tl b, hd b # Bk # list)" +apply(simp add: inv_loop5.simps inv_loop6.simps) +apply(case_tac "hd b", simp_all, auto) +done + +lemma [simp]: "inv_loop6 x ([], Bk # xs) = False" +apply(simp add: inv_loop6.simps inv_loop6_loop.simps + inv_loop6_exit.simps) +apply(auto) +done + +lemma [elim]: "\0 < x; inv_loop6 x ([], Bk # list)\ \ inv_loop6 x ([], Bk # Bk # list)" +apply(simp) +done + +lemma [simp]: "inv_loop6_exit x (b, Bk # list) = False" +apply(simp add: inv_loop6_exit.simps) +done + +lemma [elim]: "\0 < x; inv_loop6_loop x (b, Bk # list); b \ []; hd b = Bk\ + \ inv_loop6_loop x (tl b, Bk # Bk # list)" +apply(simp only: inv_loop6_loop.simps) +apply(erule_tac exE)+ +apply(rule_tac x = i in exI, rule_tac x = j in exI, + rule_tac x = "k - 1" in exI, rule_tac x = "Suc t" in exI, auto) +apply(case_tac [!] k, auto) +done + +lemma [elim]: "\0 < x; inv_loop6_loop x (b, Bk # list); b \ []; hd b = Oc\ + \ inv_loop6_exit x (tl b, Oc # Bk # list)" +apply(simp only: inv_loop6_loop.simps inv_loop6_exit.simps) +apply(erule_tac exE)+ +apply(rule_tac x = "i - 1" in exI, rule_tac x = j in exI, auto) +apply(case_tac [!] k, auto) +done + +lemma [elim]: "\0 < x; inv_loop6 x (b, Bk # list); b \ []\ \ inv_loop6 x (tl b, hd b # Bk # list)" +apply(simp add: inv_loop6.simps) +apply(case_tac "hd b", simp_all, auto) +done + +lemma [elim]: "\0 < x; inv_loop1 x (b, Oc # list)\ \ inv_loop2 x (Oc # b, list)" +apply(auto simp: inv_loop1.simps inv_loop2.simps) +apply(rule_tac x = "Suc i" in exI, auto) +done + +lemma [elim]: "\0 < x; inv_loop2 x (b, Oc # list)\ \ inv_loop2 x (b, Bk # list)" +apply(auto simp: inv_loop2.simps) +done + +lemma [elim]: "\0 < x; inv_loop3 x (b, Oc # list)\ \ inv_loop4 x (Oc # b, list)" +apply(auto simp: inv_loop3.simps inv_loop4.simps) +apply(rule_tac [!] x = i in exI, auto) +apply(rule_tac [!] x = "Suc 0" in exI, rule_tac [!] x = "j - 1" in exI, auto) +apply(case_tac [!] t, auto) +apply(case_tac [!] j, auto) +done + +lemma [elim]: "\0 < x; inv_loop4 x (b, Oc # list)\ \ inv_loop4 x (Oc # b, list)" +apply(auto simp: inv_loop4.simps) +apply(rule_tac [!] x = "i" in exI, auto) +apply(rule_tac [!] x = "Suc k" in exI, rule_tac [!] x = "t - 1" in exI, auto) +apply(case_tac [!] t, simp_all) +done + +lemma [simp]: "inv_loop5 x ([], list) = False" +apply(auto simp: inv_loop5.simps inv_loop5_exit.simps inv_loop5_loop.simps) +done + +lemma [simp]: "inv_loop5_exit x (b, Oc # list) = False" +apply(auto simp: inv_loop5_exit.simps) +done + +lemma [elim]: " \inv_loop5_loop x (b, Oc # list); b \ []; hd b = Bk\ + \ inv_loop5_exit x (tl b, Bk # Oc # list)" +apply(simp only: inv_loop5_loop.simps inv_loop5_exit.simps) +apply(erule_tac exE)+ +apply(rule_tac x = i in exI, auto) +apply(case_tac [!] k, auto) +done + +lemma [elim]: "\inv_loop5_loop x (b, Oc # list); b \ []; hd b = Oc\ + \ inv_loop5_loop x (tl b, Oc # Oc # list)" +apply(simp only: inv_loop5_loop.simps) +apply(erule_tac exE)+ +apply(rule_tac x = i in exI, rule_tac x = j in exI) +apply(rule_tac x = "k - 1" in exI, rule_tac x = "Suc t" in exI, auto) +apply(case_tac [!] k, auto) +done + +lemma [elim]: "\inv_loop5 x (b, Oc # list); b \ []\ \ + inv_loop5 x (tl b, hd b # Oc # list)" +apply(simp add: inv_loop5.simps) +apply(case_tac "hd b", simp_all, auto) +done + +lemma [elim]: "\0 < x; inv_loop6 x ([], Oc # list)\ \ + inv_loop1 x ([], Bk # Oc # list)" +apply(auto simp: inv_loop6.simps inv_loop1.simps + inv_loop6_loop.simps inv_loop6_exit.simps) +done + +lemma [elim]: "\0 < x; inv_loop6 x (b, Oc # list); b \ []\ + \ inv_loop1 x (tl b, hd b # Oc # list)" +apply(auto simp: inv_loop6.simps inv_loop1.simps + inv_loop6_loop.simps inv_loop6_exit.simps) +done + +lemma inv_loop_step: + "\inv_loop x cf; x > 0\ + \ inv_loop x (step cf (tcopy_loop, 0))" +apply(case_tac cf, case_tac c, case_tac [2] aa) +apply(auto simp: inv_loop.simps step.simps tcopy_loop_def numeral_2_eq_2 + numeral_3_eq_3 numeral_4_eq_4 numeral_5_eq_5 numeral_6_eq_6 split: if_splits) +done + +lemma inv_loop_steps: + "\inv_loop x cf; x > 0\ + \ inv_loop x (steps cf (tcopy_loop, 0) stp)" +apply(induct stp, simp add: steps.simps, simp) +apply(erule_tac inv_loop_step, simp) +done + +fun loop_stage :: "config \ nat" + where + "loop_stage (s, l, r) = (if s = 0 then 0 + else (Suc (length (takeWhile (\a. a = Oc) (rev l @ r)))))" + +fun loop_state :: "config \ nat" + where + "loop_state (s, l, r) = (if s = 2 \ hd r = Oc then 0 + else if s = 1 then 1 + else 10 - s)" + +fun loop_step :: "config \ nat" + where + "loop_step (s, l, r) = (if s = 3 then length r + else if s = 4 then length r + else if s = 5 then length l + else if s = 6 then length l + else 0)" + +definition lex_triple :: + "((nat \ (nat \ nat)) \ (nat \ (nat \ nat))) set" + where + "lex_triple \ less_than <*lex*> lex_pair" + +lemma wf_lex_triple: "wf lex_triple" + by (auto intro:wf_lex_prod simp:lex_triple_def lex_pair_def) + +fun loop_measure :: "config \ nat \ nat \ nat" + where + "loop_measure c = + (loop_stage c, loop_state c, loop_step c)" + +definition loop_LE :: "(config \ config) set" + where + "loop_LE \ (inv_image lex_triple loop_measure)" + +lemma wf_loop_le: "wf loop_LE" +by(auto intro:wf_inv_image simp: loop_LE_def wf_lex_triple) + +lemma [simp]: "inv_loop2 x ([], b) = False" +apply(auto simp: inv_loop2.simps) +done + +lemma [simp]: "inv_loop2 x (l', []) = False" +apply(auto simp: inv_loop2.simps) +done + +lemma [simp]: "inv_loop3 x (b, []) = False" +apply(auto simp: inv_loop3.simps) +done + +lemma [simp]: "inv_loop4 x ([], b) = False" +apply(auto simp: inv_loop4.simps) +done + +lemma [elim]: + "\inv_loop4 x (l', []); l' \ []; x > 0; + length (takeWhile (\a. a = Oc) (rev l' @ [Oc])) \ + length (takeWhile (\a. a = Oc) (rev l'))\ + \ length (takeWhile (\a. a = Oc) (rev l' @ [Oc])) < length (takeWhile (\a. a = Oc) (rev l'))" +apply(auto simp: inv_loop4.simps) +apply(case_tac [!] j, simp_all add: List.takeWhile_tail) +done + + +lemma [elim]: + "\inv_loop4 x (l', Bk # list); l' \ []; 0 < x; + length (takeWhile (\a. a = Oc) (rev l' @ Oc # list)) \ + length (takeWhile (\a. a = Oc) (rev l' @ Bk # list))\ + \ length (takeWhile (\a. a = Oc) (rev l' @ Oc # list)) < + length (takeWhile (\a. a = Oc) (rev l' @ Bk # list))" +apply(auto simp: inv_loop4.simps) +done + +lemma takeWhile_replicate_append: + "P a \ takeWhile P (a\x @ ys) = a\x @ takeWhile P ys" +apply(induct x, auto) +done + +lemma takeWhile_replicate: + "P a \ takeWhile P (a\x) = a\x" +by(induct x, auto) + +lemma [elim]: + "\inv_loop5 x (l', Bk # list); l' \ []; 0 < x; + length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) \ + length (takeWhile (\a. a = Oc) (rev l' @ Bk # list))\ + \ length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) < + length (takeWhile (\a. a = Oc) (rev l' @ Bk # list))" +apply(auto simp: inv_loop5.simps inv_loop5_exit.simps) +apply(case_tac [!] j, simp_all) +apply(case_tac [!] "nat", simp_all) +apply(case_tac nata, simp_all add: List.takeWhile_tail) +apply(simp add: takeWhile_replicate_append takeWhile_replicate) +apply(case_tac nata, simp_all add: List.takeWhile_tail) +done + +lemma [elim]: "\inv_loop1 x (l', Oc # list)\ \ hd list = Oc" +apply(auto simp: inv_loop1.simps) +done + +lemma [elim]: + "\inv_loop6 x (l', Bk # list); l' \ []; 0 < x; + length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) \ + length (takeWhile (\a. a = Oc) (rev l' @ Bk # list))\ + \ length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) < + length (takeWhile (\a. a = Oc) (rev l' @ Bk # list))" +apply(auto simp: inv_loop6.simps) +apply(case_tac l', simp_all) +done + +lemma [elim]: + "\inv_loop2 x (l', Oc # list); l' \ []; 0 < x\ \ + length (takeWhile (\a. a = Oc) (rev l' @ Bk # list)) < + length (takeWhile (\a. a = Oc) (rev l' @ Oc # list))" +apply(auto simp: inv_loop2.simps) +apply(simp_all add: takeWhile_tail takeWhile_replicate_append + takeWhile_replicate) +done + +lemma [elim]: + "\inv_loop5 x (l', Oc # list); l' \ []; 0 < x; + length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) \ + length (takeWhile (\a. a = Oc) (rev l' @ Oc # list))\ + \ length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) < + length (takeWhile (\a. a = Oc) (rev l' @ Oc # list))" +apply(auto simp: inv_loop5.simps) +apply(case_tac l', auto) +done + + +lemma[elim]: + "\inv_loop6 x (l', Oc # list); l' \ []; 0 < x; + length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) + \ length (takeWhile (\a. a = Oc) (rev l' @ Oc # list))\ + \ length (takeWhile (\a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) < + length (takeWhile (\a. a = Oc) (rev l' @ Oc # list))" +apply(case_tac l') +apply(auto simp: inv_loop6.simps) +done + +lemma loop_halt: + "\x > 0; inv_loop x (Suc 0, l, r)\ \ + \ stp. is_final (steps (Suc 0, l, r) (tcopy_loop, 0) stp)" +proof(rule_tac LE = loop_LE in halt_lemma) + show "wf loop_LE" by(intro wf_loop_le) +next + assume h: "0 < x" and g: "inv_loop x (Suc 0, l, r)" + show "\n. \ is_final (steps (Suc 0, l, r) (tcopy_loop, 0) n) \ + (steps (Suc 0, l, r) (tcopy_loop, 0) (Suc n), steps (Suc 0, l, r) (tcopy_loop, 0) n) \ loop_LE" + proof(rule_tac allI, rule_tac impI) + fix n + assume a: "\ is_final (steps (Suc 0, l, r) (tcopy_loop, 0) n)" + obtain s' l' r' where d: "(steps (Suc 0, l, r) (tcopy_loop, 0) n) = (s', l', r')" + by(case_tac "(steps (Suc 0, l, r) (tcopy_loop, 0) n)", auto) + hence "inv_loop x (s', l', r') \ s' \ 0" + using h g + apply(drule_tac stp = n in inv_loop_steps, auto) + using a + apply(simp) + done + hence "(step(s', l', r') (tcopy_loop, 0), s', l', r') \ loop_LE" + using h + apply(case_tac r', case_tac [2] a) + apply(auto simp: inv_loop.simps step.simps tcopy_loop_def + numeral_2_eq_2 numeral_3_eq_3 numeral_4_eq_4 + numeral_5_eq_5 numeral_6_eq_6 loop_LE_def lex_triple_def lex_pair_def split: if_splits) + done + thus "(steps (Suc 0, l, r) (tcopy_loop, 0) (Suc n), + steps (Suc 0, l, r) (tcopy_loop, 0) n) \ loop_LE" + using d + apply(simp add: step_red) + done + qed +qed + +lemma loop_correct: + "x > 0 \ + {inv_loop1 x} (tcopy_loop, 0) {inv_loop0 x}" +proof(rule_tac HoareI) + fix l r + assume h: "0 < x" + "inv_loop1 x (l, r)" + hence "\ stp. is_final (steps (Suc 0, l, r) (tcopy_loop, 0) stp)" + apply(rule_tac loop_halt, simp_all add: inv_loop.simps) + done + then obtain stp where "is_final (steps (Suc 0, l, r) (tcopy_loop, 0) stp)" .. + moreover have "inv_loop x (steps (Suc 0, l, r) (tcopy_loop, 0) stp)" + apply(rule_tac inv_loop_steps) + using h by(simp_all add: inv_loop.simps) + ultimately show + "\n. is_final (steps (1, l, r) (tcopy_loop, 0) n) \ + inv_loop0 x holds_for steps (1, l, r) (tcopy_loop, 0) n" + using h + apply(rule_tac x = stp in exI) + apply(case_tac "(steps (Suc 0, l, r) (tcopy_loop, 0) stp)", + simp add: inv_init.simps inv_loop.simps) + done +qed + +definition tcopy_end :: "instr list" + where + "tcopy_end \ [(L, 0), (R, 2), (W1, 3), (L, 4), + (R, 2), (R, 2), (L, 5), (W0, 4), + (R, 0), (L, 5)]" + +fun inv_end1 :: "nat \ tape \ bool" + where + "inv_end1 x (l, r) = (x > 0 \ l = [Bk] \ r = Oc # Bk\x @ Oc\x)" + +fun inv_end2 :: "nat \ tape \ bool" + where + "inv_end2 x (l, r) = (\ i j. i + j = Suc x \ x > 0 \ l = Oc\i @ [Bk] \ r = Bk\j @ Oc\)" + +fun inv_end3 :: "nat \ tape \ bool" + where + "inv_end3 x (l, r) = + (\ i j. x > 0 \ i + j = x \ l = Oc\i @ [Bk] \ r = Oc # Bk\j@ Oc\x )" + +fun inv_end4 :: "nat \ tape \ bool" + where + "inv_end4 x (l, r) = (\ any. x > 0 \ l = Oc\x @ [Bk] \ r = any#Oc\x)" + +fun inv_end5_loop :: "nat \ tape \ bool" + where + "inv_end5_loop x (l, r) = + (\ i j. i + j = x \ x > 0 \ j > 0 \ l = Oc\i @ [Bk] \ r = Oc\j @ Bk # Oc\x)" + +fun inv_end5_exit :: "nat \ tape \ bool" + where + "inv_end5_exit x (l, r) = (x > 0 \ l = [] \ r = Bk # Oc\x @ Bk # Oc\x)" + +fun inv_end5 :: "nat \ tape \ bool" + where + "inv_end5 x (l, r) = (inv_end5_loop x (l, r) \ inv_end5_exit x (l, r))" + +fun inv_end0 :: "nat \ tape \ bool" + where + "inv_end0 x (l, r) = (x > 0 \ l = [Bk] \ r = Oc\x @ Bk # Oc\x)" + +fun inv_end :: "nat \ config \ bool" + where + "inv_end x (s, l, r) = (if s = 0 then inv_end0 x (l, r) + else if s = 1 then inv_end1 x (l, r) + else if s = 2 then inv_end2 x (l, r) + else if s = 3 then inv_end3 x (l, r) + else if s = 4 then inv_end4 x (l, r) + else if s = 5 then inv_end5 x (l, r) + else False)" + +declare inv_end.simps[simp del] inv_end1.simps[simp del] + inv_end0.simps[simp del] inv_end2.simps[simp del] + inv_end3.simps[simp del] inv_end4.simps[simp del] + inv_end5.simps[simp del] + +lemma [simp]: "inv_end1 x (b, []) = False" +apply(auto simp: inv_end1.simps) +done + +lemma [simp]: "inv_end2 x (b, []) = False" +apply(auto simp: inv_end2.simps) +done + +lemma [simp]: "inv_end3 x (b, []) = False" +apply(auto simp: inv_end3.simps) +done + +thm inv_end4.simps +lemma [simp]: "inv_end4 x (b, []) = False" +apply(auto simp: inv_end4.simps) +done + +lemma [simp]: "inv_end5 x (b, []) = False" +apply(auto simp: inv_end5.simps) +done + +lemma [simp]: "inv_end1 x ([], list) = False" +apply(auto simp: inv_end1.simps) +done + +lemma [elim]: "\0 < x; inv_end1 x (b, Bk # list); b \ []\ + \ inv_end0 x (tl b, hd b # Bk # list)" +apply(auto simp: inv_end1.simps inv_end0.simps) +done + +lemma [elim]: "\0 < x; inv_end2 x (b, Bk # list)\ + \ inv_end3 x (b, Oc # list)" +apply(auto simp: inv_end2.simps inv_end3.simps) +apply(rule_tac x = "j - 1" in exI) +apply(case_tac j, simp_all) +apply(case_tac x, simp_all) +done + +lemma [elim]: "\0 < x; inv_end3 x (b, Bk # list)\ \ inv_end2 x (Bk # b, list)" +apply(auto simp: inv_end2.simps inv_end3.simps) +done + +lemma [elim]: "\0 < x; inv_end4 x ([], Bk # list)\ \ + inv_end5 x ([], Bk # Bk # list)" +apply(auto simp: inv_end4.simps inv_end5.simps) +done + +lemma [elim]: "\0 < x; inv_end4 x (b, Bk # list); b \ []\ \ + inv_end5 x (tl b, hd b # Bk # list)" +apply(auto simp: inv_end4.simps inv_end5.simps) +apply(rule_tac x = 1 in exI, simp) +done + +lemma [elim]: "\0 < x; inv_end5 x (b, Bk # list)\ \ inv_end0 x (Bk # b, list)" +apply(auto simp: inv_end5.simps inv_end0.simps) +apply(case_tac [!] j, simp_all) +done + +lemma [elim]: "\0 < x; inv_end1 x (b, Oc # list)\ \ inv_end2 x (Oc # b, list)" +apply(auto simp: inv_end1.simps inv_end2.simps) +done + +lemma [elim]: "\0 < x; inv_end2 x ([], Oc # list)\ \ + inv_end4 x ([], Bk # Oc # list)" +apply(auto simp: inv_end2.simps inv_end4.simps) +done + +lemma [elim]: "\0 < x; inv_end2 x (b, Oc # list); b \ []\ \ + inv_end4 x (tl b, hd b # Oc # list)" +apply(auto simp: inv_end2.simps inv_end4.simps) +apply(case_tac [!] j, simp_all) +done + +lemma [elim]: "\0 < x; inv_end3 x (b, Oc # list)\ \ inv_end2 x (Oc # b, list)" +apply(auto simp: inv_end2.simps inv_end3.simps) +done + +lemma [elim]: "\0 < x; inv_end4 x (b, Oc # list)\ \ inv_end4 x (b, Bk # list)" +apply(auto simp: inv_end2.simps inv_end4.simps) +done + +lemma [elim]: "\0 < x; inv_end5 x ([], Oc # list)\ \ inv_end5 x ([], Bk # Oc # list)" +apply(auto simp: inv_end2.simps inv_end5.simps) +done + +declare inv_end5_loop.simps[simp del] + inv_end5_exit.simps[simp del] + +lemma [simp]: "inv_end5_exit x (b, Oc # list) = False" +apply(auto simp: inv_end5_exit.simps) +done + +lemma [simp]: "inv_end5_loop x (tl b, Bk # Oc # list) = False" +apply(auto simp: inv_end5_loop.simps) +apply(case_tac [!] j, simp_all) +done + +lemma [elim]: + "\0 < x; inv_end5_loop x (b, Oc # list); b \ []; hd b = Bk\ \ + inv_end5_exit x (tl b, Bk # Oc # list)" +apply(auto simp: inv_end5_loop.simps inv_end5_exit.simps) +apply(case_tac [!] i, simp_all) +done + +lemma [elim]: + "\0 < x; inv_end5_loop x (b, Oc # list); b \ []; hd b = Oc\ \ + inv_end5_loop x (tl b, Oc # Oc # list)" +apply(simp only: inv_end5_loop.simps inv_end5_exit.simps) +apply(erule_tac exE)+ +apply(rule_tac x = "i - 1" in exI, + rule_tac x = "Suc j" in exI, auto) +apply(case_tac [!] i, simp_all) +done + +lemma [elim]: "\0 < x; inv_end5 x (b, Oc # list); b \ []\ \ + inv_end5 x (tl b, hd b # Oc # list)" +apply(simp add: inv_end2.simps inv_end5.simps) +apply(case_tac "hd b", simp_all, auto) +done + +lemma inv_end_step: + "\x > 0; + inv_end x cf\ + \ inv_end x (step cf (tcopy_end, 0))" +apply(case_tac cf, case_tac c, case_tac [2] aa) +apply(auto simp: inv_end.simps step.simps tcopy_end_def numeral_2_eq_2 + numeral_3_eq_3 numeral_4_eq_4 numeral_5_eq_5 split: if_splits) +done + +lemma inv_end_steps: + "\x > 0; inv_end x cf\ +\ inv_end x (steps cf (tcopy_end, 0) stp)" +apply(induct stp, simp add:steps.simps, simp) +apply(erule_tac inv_end_step, simp) +done + +fun end_state :: "config \ nat" + where + "end_state (s, l, r) = + (if s = 0 then 0 + else if s = 1 then 5 + else if s = 2 \ s = 3 then 4 + else if s = 4 then 3 + else if s = 5 then 2 + else 0)" + +fun end_stage :: "config \ nat" + where + "end_stage (s, l, r) = + (if s = 2 \ s = 3 then (length r) + else 0)" + +fun end_step :: "config \ nat" + where + "end_step (s, l, r) = + (if s = 4 then (if hd r = Oc then 1 else 0) + else if s = 5 then length l + else if s = 2 then 1 + else if s = 3 then 0 + else 0)" + +fun end_measure :: "config \ nat \ nat \ nat" + where + "end_measure c = + (end_state c, end_stage c, end_step c)" + +definition end_LE :: "(config \ config) set" + where + "end_LE \ (inv_image lex_triple end_measure)" + +lemma wf_end_le: "wf end_LE" +by(auto intro:wf_inv_image simp: end_LE_def wf_lex_triple) + +lemma [simp]: "inv_end5 x ([], Oc # list) = False" +apply(auto simp: inv_end5.simps inv_end5_loop.simps) +done + +lemma end_halt: + "\x > 0; inv_end x (Suc 0, l, r)\ \ + \ stp. is_final (steps (Suc 0, l, r) (tcopy_end, 0) stp)" +proof(rule_tac LE = end_LE in halt_lemma) + show "wf end_LE" by(intro wf_end_le) +next + assume great: "0 < x" + and inv_start: "inv_end x (Suc 0, l, r)" + show "\n. \ is_final (steps (Suc 0, l, r) (tcopy_end, 0) n) \ + (steps (Suc 0, l, r) (tcopy_end, 0) (Suc n), steps (Suc 0, l, r) (tcopy_end, 0) n) \ end_LE" + proof(rule_tac allI, rule_tac impI) + fix n + assume notfinal: "\ is_final (steps (Suc 0, l, r) (tcopy_end, 0) n)" + obtain s' l' r' where d: "steps (Suc 0, l, r) (tcopy_end, 0) n = (s', l', r')" + apply(case_tac "steps (Suc 0, l, r) (tcopy_end, 0) n", auto) + done + hence "inv_end x (s', l', r') \ s' \ 0" + using great inv_start notfinal + apply(drule_tac stp = n in inv_end_steps, auto) + done + hence "(step (s', l', r') (tcopy_end, 0), s', l', r') \ end_LE" + apply(case_tac r', case_tac [2] a) + apply(auto simp: inv_end.simps step.simps tcopy_end_def + numeral_2_eq_2 numeral_3_eq_3 numeral_4_eq_4 + numeral_5_eq_5 numeral_6_eq_6 end_LE_def lex_triple_def lex_pair_def split: if_splits) + done + thus "(steps (Suc 0, l, r) (tcopy_end, 0) (Suc n), + steps (Suc 0, l, r) (tcopy_end, 0) n) \ end_LE" + using d + by simp + qed +qed + +lemma end_correct: + "x > 0 \ + {inv_end1 x} (tcopy_end, 0) {inv_end0 x}" +proof(rule_tac HoareI) + fix l r + assume h: "0 < x" + "inv_end1 x (l, r)" + hence "\ stp. is_final (steps (Suc 0, l, r) (tcopy_end, 0) stp)" + apply(rule_tac end_halt, simp_all add: inv_end.simps) + done + then obtain stp where "is_final (steps (Suc 0, l, r) (tcopy_end, 0) stp)" .. + moreover have "inv_end x (steps (Suc 0, l, r) (tcopy_end, 0) stp)" + apply(rule_tac inv_end_steps) + using h by(simp_all add: inv_end.simps) + ultimately show + "\n. is_final (steps (1, l, r) (tcopy_end, 0) n) \ + inv_end0 x holds_for steps (1, l, r) (tcopy_end, 0) n" + using h + apply(rule_tac x = stp in exI) + apply(case_tac "(steps (Suc 0, l, r) (tcopy_end, 0) stp)", + simp add: inv_end.simps) + done +qed + +definition tcopy :: "instr list" + where + "tcopy = ((tcopy_init |+| tcopy_loop) |+| tcopy_end)" + +lemma [intro]: "tm_wf (tcopy_init, 0)" +by(auto simp: tm_wf.simps tcopy_init_def) + +lemma [intro]: "tm_wf (tcopy_loop, 0)" +by(auto simp: tm_wf.simps tcopy_loop_def) + +lemma [intro]: "tm_wf (tcopy_end, 0)" +by(auto simp: tm_wf.simps tcopy_end_def) + +lemma [intro]: "\tm_wf (A, 0); tm_wf (B, 0)\ \ tm_wf (A |+| B, 0)" +apply(auto simp: tm_wf.simps shift.simps adjust.simps length_comp + tm_comp.simps) +done + +lemma tcopy_correct1: + "\x > 0\ \ {inv_init1 x} (tcopy, 0) {inv_end0 x}" +proof(simp add: tcopy_def, rule_tac Hoare_plus_halt) + show "inv_loop0 x \ inv_end1 x" + by(auto simp: inv_end1.simps inv_loop1.simps assert_imp_def) +next + show "tm_wf (tcopy_init |+| tcopy_loop, 0)" by auto +next + show "tm_wf (tcopy_end, 0)" by auto +next + assume "0 < x" + thus "{inv_init1 x} (tcopy_init |+| tcopy_loop, 0) {inv_loop0 x}" + proof(rule_tac Hoare_plus_halt) + show "inv_init0 x \ inv_loop1 x" + apply(auto simp: inv_init0.simps inv_loop1.simps assert_imp_def) + apply(rule_tac x = "Suc 0" in exI, auto) + done + next + show "tm_wf (tcopy_init, 0)" by auto + next + show "tm_wf (tcopy_loop, 0)" by auto + next + assume "0 < x" + thus "{inv_init1 x} (tcopy_init, 0) {inv_init0 x}" + by(erule_tac init_correct) + next + assume "0 < x" + thus "{inv_loop1 x} (tcopy_loop, 0) {inv_loop0 x}" + by(erule_tac loop_correct) + qed +next + assume "0 < x" + thus "{inv_end1 x} (tcopy_end, 0) {inv_end0 x}" + by(erule_tac end_correct) +qed + +section {* + The {\em Dithering} Turing Machine +*} + +text {* + The {\em Dithering} TM, when the input is @{text "1"}, it will loop forever, otherwise, it will + terminate. +*} +definition dither :: "instr list" + where + "dither \ [(W0, 1), (R, 2), (L, 1), (L, 0)] " + +lemma dither_halt_rs: + "\ stp. steps (Suc 0, Bk\m, [Oc, Oc]) (dither, 0) stp = + (0, Bk\m, [Oc, Oc])" +apply(rule_tac x = "Suc (Suc (Suc 0))" in exI) +apply(simp add: dither_def steps.simps + step.simps fetch.simps numeral_2_eq_2) +done + +lemma dither_unhalt_state: + "(steps (Suc 0, Bk\m, [Oc]) (dither, 0) stp = + (Suc 0, Bk\m, [Oc])) \ + (steps (Suc 0, Bk\m, [Oc]) (dither, 0) stp = (2, Oc # Bk\m, []))" + apply(induct stp, simp add: steps.simps) + apply(simp add: step_red, auto) + apply(auto simp: step.simps fetch.simps dither_def numeral_2_eq_2) + done + +lemma dither_unhalt_rs: + "\ is_final (steps (Suc 0, Bk\m, [Oc]) (dither,0) stp)" +using dither_unhalt_state[of m stp] +apply(auto) +done + +section {* + The final diagnal arguments to show the undecidability of Halting problem. +*} + +text {* + @{text "haltP tp x"} means TM @{text "tp"} terminates on input @{text "x"} + and the final configuration is standard. +*} + + +fun tape_of_nat_list :: "nat list \ cell list" ("< _ >" [0] 100) + where + "tape_of_nat_list [] = []" | + "tape_of_nat_list [n] = Oc\(Suc n)" | + "tape_of_nat_list (n#ns) = Oc\(Suc n) @ Bk # (tape_of_nat_list ns)" + +definition haltP :: "tprog \ nat list \ bool" + where + "haltP t lm = (\n a b c. steps (Suc 0, [], ) t n = (0, Bk\a, Oc\b @ Bk\c))" + +lemma [intro]: "tm_wf (tcopy, 0)" +by(auto simp: tcopy_def) + +lemma [intro]: "tm_wf (dither, 0)" +apply(auto simp: tm_wf.simps dither_def) +done + +text {* + The following lemma shows the meaning of @{text "tinres"} with respect to + one step execution. + *} +lemma tinres_step: + "\tinres l l'; step (ss, l, r) (t, 0) = (sa, la, ra); + step (ss, l', r) (t, 0) = (sb, lb, rb)\ + \ tinres la lb \ ra = rb \ sa = sb" +apply(case_tac ss, case_tac [!]r, case_tac [!] "a::cell") +apply(auto simp: step.simps fetch.simps + split: if_splits ) +apply(case_tac [!] "t ! (2 * nat)", + auto simp: tinres_def split: if_splits) +apply(case_tac [1-8] a, auto split: if_splits) +apply(case_tac [!] "t ! (2 * nat)", + auto simp: tinres_def split: if_splits) +apply(case_tac [1-4] a, auto split: if_splits) +apply(case_tac [!] "t ! Suc (2 * nat)", + auto simp: if_splits) +apply(case_tac [!] aa, auto split: if_splits) +done + +text {* + The following lemma shows the meaning of @{text "tinres"} with respect to + many step execution. + *} + +lemma tinres_steps: + "\tinres l l'; steps (ss, l, r) (t, 0) stp = (sa, la, ra); + steps (ss, l', r) (t, 0) stp = (sb, lb, rb)\ + \ tinres la lb \ ra = rb \ sa = sb" +apply(induct stp arbitrary: sa la ra sb lb rb, simp add: steps.simps) +apply(simp add: step_red) +apply(case_tac "(steps (ss, l, r) (t, 0) stp)") +apply(case_tac "(steps (ss, l', r) (t, 0) stp)") +proof - + fix stp sa la ra sb lb rb a b c aa ba ca + assume ind: "\sa la ra sb lb rb. \steps (ss, l, r) (t, 0) stp = (sa, (la::cell list), ra); + steps (ss, l', r) (t, 0) stp = (sb, lb, rb)\ \ tinres la lb \ ra = rb \ sa = sb" + and h: " tinres l l'" "step (steps (ss, l, r) (t, 0) stp) (t, 0) = (sa, la, ra)" + "step (steps (ss, l', r) (t, 0) stp) (t, 0) = (sb, lb, rb)" "steps (ss, l, r) (t, 0) stp = (a, b, c)" + "steps (ss, l', r) (t, 0) stp = (aa, ba, ca)" + have "tinres b ba \ c = ca \ a = aa" + apply(rule_tac ind, simp_all add: h) + done + thus "tinres la lb \ ra = rb \ sa = sb" + apply(rule_tac l = b and l' = ba and r = c and ss = a + and t = t in tinres_step) + using h + apply(simp, simp, simp) + done +qed + +lemma length_eq: "xs = ys \ length xs = length ys" +by auto + +lemma tinres_ex1: "tinres (Bk \ nb) b \ \nb. b = Bk \ nb" +apply(auto simp: tinres_def replicate_add[THEN sym]) +apply(case_tac "nb \ n") +apply(subgoal_tac "\ d. nb = d + n", auto simp: replicate_add) +apply arith +apply(drule_tac length_eq, simp) +done + +lemma Hoare_weak: + "\{P} (p, off) {Q}; P'\P; Q\Q'\ \ {P'} (p, off) {Q'}" +using Hoare_def +proof(auto simp: assert_imp_def) + fix l r + assume + ho1: "\l r. P (l, r) \ (\n. is_final (steps (Suc 0, l, r) (p, off) n) + \ Q holds_for steps (Suc 0, l, r) (p, off) n)" + and imp1: "\l r. P' (l, r) \ P (l, r)" + and imp2: "\l r. Q (l, r) \ Q' (l, r)" + and cond: "P' (l, r)" + and ho2: "\P a b Q. {P} (a, b) {Q} \ \l r. P (l, r) \ + (\n. is_final (steps (Suc 0, l, r) (a, b) n) \ Q holds_for steps (Suc 0, l, r) (a, b) n)" + have "P (l, r)" + using cond imp1 by auto + hence "(\n. is_final (steps (Suc 0, l, r) (p, off) n) + \ Q holds_for steps (Suc 0, l, r) (p, off) n)" + using ho1 by auto + from this obtain n where "is_final (steps (Suc 0, l, r) (p, off) n) + \ Q holds_for steps (Suc 0, l, r) (p, off) n" .. + thus "\n. is_final (steps (Suc 0, l, r) (p, off) n) \ + Q' holds_for steps (Suc 0, l, r) (p, off) n" + apply(rule_tac x = n in exI, auto) + apply(case_tac "steps (Suc 0, l, r) (p, off) n", simp) + using imp2 + by simp +qed + +text {* + The following locale specifies that TM @{text "H"} can be used to solve + the {\em Halting Problem} and @{text "False"} is going to be derived + under this locale. Therefore, the undecidability of {\em Halting Problem} + is established. +*} + +locale uncomputable = + -- {* The coding function of TM, interestingly, the detailed definition of this + funciton @{text "code"} does not affect the final result. *} + fixes code :: "instr list \ nat" + -- {* + The TM @{text "H"} is the one which is assummed being able to solve the Halting problem. + *} + and H :: "instr list" + assumes h_wf[intro]: "tm_wf (H, 0)" + -- {* + The following two assumptions specifies that @{text "H"} does solve the Halting problem. + *} + and h_case: + "\ M n. \(haltP (M, 0) lm)\ \ + \ na nb. (steps (Suc 0, [], ) (H, 0) na = (0, Bk\nb, [Oc]))" + and nh_case: + "\ M n. \(\ haltP (M, 0) lm)\ \ + \ na nb. (steps (Suc 0, [], ) (H, 0) na = (0, Bk\nb, [Oc, Oc]))" +begin + +lemma h_newcase: + "\ M n. haltP (M, 0) lm \ + \ na nb. (steps (Suc 0, Bk\x , ) (H, 0) na = (0, Bk\nb, [Oc]))" +proof - + fix M n + assume "haltP (M, 0) lm" + hence "\ na nb. (steps (Suc 0, [], ) (H, 0) na + = (0, Bk\nb, [Oc]))" + apply(erule_tac h_case) + done + from this obtain na nb where + cond1:"(steps (Suc 0, [], ) (H, 0) na + = (0, Bk\nb, [Oc]))" by blast + thus "\ na nb. (steps (Suc 0, Bk\x, ) (H, 0) na = (0, Bk\nb, [Oc]))" + proof(rule_tac x = na in exI, case_tac "steps (Suc 0, Bk\x, ) (H, 0) na", simp) + fix a b c + assume cond2: "steps (Suc 0, Bk\x, ) (H, 0) na = (a, b, c)" + have "tinres (Bk\nb) b \ [Oc] = c \ 0 = a" + proof(rule_tac tinres_steps) + show "tinres [] (Bk\x)" + apply(simp add: tinres_def) + apply(auto) + done + next + show "(steps (Suc 0, [], ) (H, 0) na + = (0, Bk\nb, [Oc]))" + by(simp add: cond1) + next + show "steps (Suc 0, Bk\x, ) (H, 0) na = (a, b, c)" + by(simp add: cond2) + qed + thus "a = 0 \ (\nb. b = (Bk\nb)) \ c = [Oc]" + by(auto elim: tinres_ex1) + qed +qed + +lemma nh_newcase: "\ M n. \\ (haltP (M, 0) lm)\ \ + \ na nb. (steps (Suc 0, Bk\x, ) (H, 0) na = (0, Bk\nb, [Oc, Oc]))" +proof - + fix M n + assume "\ haltP (M, 0) lm" + hence "\ na nb. (steps (Suc 0, [], ) (H, 0) na + = (0, Bk\nb, [Oc, Oc]))" + apply(erule_tac nh_case) + done + from this obtain na nb where + cond1: "(steps (Suc 0, [], ) (H, 0) na + = (0, Bk\nb, [Oc, Oc]))" by blast + thus "\ na nb. (steps (Suc 0, Bk\x, ) (H, 0) na = (0, Bk\nb, [Oc, Oc]))" + proof(rule_tac x = na in exI, case_tac "steps (Suc 0, Bk\x, ) (H, 0) na", simp) + fix a b c + assume cond2: "steps (Suc 0, Bk\x, ) (H, 0) na = (a, b, c)" + have "tinres (Bk\nb) b \ [Oc, Oc] = c \ 0 = a" + proof(rule_tac tinres_steps) + show "tinres [] (Bk\x)" + apply(auto simp: tinres_def) + done + next + show "(steps (Suc 0, [], ) (H, 0) na + = (0, Bk\nb, [Oc, Oc]))" + by(simp add: cond1) + next + show "steps (Suc 0, Bk\x, ) (H, 0) na = (a, b, c)" + by(simp add: cond2) + qed + thus "a = 0 \ (\nb. b = Bk\nb) \ c = [Oc, Oc]" + by(auto elim: tinres_ex1) + qed +qed + +(* +lemma haltP_weaking: + "haltP (tcontra H) (code (tcontra H)) \ + \stp. isS0 (steps (Suc 0, [], Oc\<^bsup>code (tcontra H)\<^esup>) + ((tcopy |+| H) |+| dither) stp)" + apply(simp add: haltP_def, auto) + apply(rule_tac x = n in exI, simp add: isS0_def tcontra_def) + done +*) + +definition tcontra :: "instr list \ instr list" + where + "tcontra h \ ((tcopy |+| h) |+| dither)" + +declare replicate_Suc[simp del] + +lemma uh_h: "\ haltP (tcontra H, 0) [code (tcontra H)] + \ haltP (tcontra H, 0) [code (tcontra H)]" +proof(simp only: tcontra_def) + let ?tcontr = "(tcopy |+| H) |+| dither" + let ?cn = "Suc (code ?tcontr)" + let ?P1 = "\ (l, r). (l = [] \ (r::cell list) = Oc\(?cn))" + let ?Q1 = "\ (l, r). (l = [Bk] \ r = Oc\?cn @ Bk # Oc\?cn)" + let ?P2 = "\ (l, r). (l = [Bk] \ r = Oc\?cn @ Bk # Oc\?cn)" + let ?Q2 = "\(l, r). (\nd. l = Bk \ nd) \ r = [Oc, Oc]" + let ?P3 = ?Q2 + let ?Q3 = ?P3 + assume h: "\ haltP (?tcontr, 0) [code ?tcontr]" + have "{?P1} (?tcontr, 0) {?Q3}" + proof(rule_tac Hoare_plus_halt, auto) + show "?Q2 \ ?P3" + apply(simp add: assert_imp_def) + done + next + show "{?P1} (tcopy|+|H, 0) {?Q2}" + proof(rule_tac Hoare_plus_halt, auto) + show "?Q1 \ ?P2" + apply(simp add: assert_imp_def) + done + next + show "{?P1} (tcopy, 0) {?Q1}" + proof - + have g: "{inv_init1 ?cn} (tcopy, 0) {inv_end0 ?cn}" + by(rule_tac tcopy_correct1, simp) + thus "?thesis" + proof(rule_tac Hoare_weak) + show "{inv_init1 ?cn} (tcopy, 0) + {inv_end0 ?cn} " using g by simp + next + show "?P1 \ inv_init1 (?cn)" + apply(simp add: inv_init1.simps assert_imp_def) + done + next + show "inv_end0 ?cn \ ?Q1" + apply(simp add: assert_imp_def inv_end0.simps) + done + qed + qed + next + show "{?P2} (H, 0) {?Q2}" + using Hoare_def nh_newcase[of ?tcontr "[code ?tcontr]" 1] h + apply(auto) + apply(rule_tac x = na in exI) + apply(simp add: replicate_Suc) + done + qed + next + show "{?P3}(dither, 0){?Q3}" + using Hoare_def + proof(auto) + fix nd + show "\n. is_final (steps (Suc 0, Bk \ nd, [Oc, Oc]) (dither, 0) n) \ + (\(l, r). (\nd. l = Bk \ nd) \ r = [Oc, Oc]) + holds_for steps (Suc 0, Bk \ nd, [Oc, Oc]) (dither, 0) n" + using dither_halt_rs[of nd] + apply(auto) + apply(rule_tac x = stp in exI, simp) + done + qed + qed + thus "False" + using h + apply(auto simp: haltP_def Hoare_def) + apply(erule_tac x = n in allE) + apply(case_tac "steps (Suc 0, [], Oc \ ?cn) (?tcontr, 0) n") + apply(simp, auto) + apply(erule_tac x = 2 in allE, erule_tac x = 0 in allE) + apply(simp add: numeral_2_eq_2 replicate_Suc) + done +qed + + +lemma h_uh: "haltP (tcontra H, 0) [code (tcontra H)] + \ \ haltP (tcontra H, 0) [code (tcontra H)]" +proof(simp only: tcontra_def) + let ?tcontr = "(tcopy |+| H) |+| dither" + let ?cn = "Suc (code ?tcontr)" + let ?P1 = "\ (l, r). (l = [] \ (r::cell list) = Oc\(?cn))" + let ?Q1 = "\ (l, r). (l = [Bk] \ r = Oc\?cn @ Bk # Oc\?cn)" + let ?P2 = "\ (l, r). (l = [Bk] \ r = Oc\?cn @ Bk # Oc\?cn)" + let ?Q2 = "\(l, r). (\nd. l = Bk \ nd) \ r = [Oc]" + let ?P3 = ?Q2 + assume h: "haltP (?tcontr, 0) [code ?tcontr]" + have "{?P1} (?tcontr, 0)" + proof(rule_tac Hoare_plus_unhalt, auto) + show "?Q2 \ ?P3" + apply(simp add: assert_imp_def) + done + next + show "{?P1} (tcopy|+|H, 0) {?Q2}" + proof(rule_tac Hoare_plus_halt, auto) + show "?Q1 \ ?P2" + apply(simp add: assert_imp_def) + done + next + show "{?P1} (tcopy, 0) {?Q1}" + proof - + have g: "{inv_init1 ?cn} (tcopy, 0) {inv_end0 ?cn}" + by(rule_tac tcopy_correct1, simp) + thus "?thesis" + proof(rule_tac Hoare_weak) + show "{inv_init1 ?cn} (tcopy, 0) + {inv_end0 ?cn} " using g by simp + next + show "?P1 \ inv_init1 (?cn)" + apply(simp add: inv_init1.simps assert_imp_def) + done + next + show "inv_end0 ?cn \ ?Q1" + apply(simp add: assert_imp_def inv_end0.simps) + done + qed + qed + next + show "{?P2} (H, 0) {?Q2}" + using Hoare_def h_newcase[of ?tcontr "[code ?tcontr]" 1] h + apply(auto) + apply(rule_tac x = na in exI) + apply(simp add: replicate_Suc) + done + qed + next + show "{?P3}(dither, 0)" + using Hoare_unhalt_def + proof(auto) + fix nd n + assume "is_final (steps (Suc 0, Bk \ nd, [Oc]) (dither, 0) n)" + thus "False" + using dither_unhalt_rs[of nd n] + by simp + qed + qed + thus "\ True" + using h + apply(auto simp: haltP_def Hoare_unhalt_def) + apply(erule_tac x = n in allE) + apply(case_tac "steps (Suc 0, [], Oc \ ?cn) (?tcontr, 0) n", simp) + done +qed + +text {* + @{text "False"} is finally derived. +*} + +lemma false: "False" +using uh_h h_uh +by auto +end + +end +