thys/uncomputable.thy
changeset 44 2f765afc1f7e
child 45 9192a969f044
equal deleted inserted replaced
43:a8785fa80278 44:2f765afc1f7e
       
     1 (* Title: Turing machine's definition and its charater
       
     2    Author: XuJian <xujian817@hotmail.com>
       
     3    Maintainer: Xujian
       
     4 *)
       
     5 
       
     6 header {* Undeciablity of the {\em Halting problem} *}
       
     7 
       
     8 theory uncomputable
       
     9 imports Main turing_basic
       
    10 begin
       
    11 
       
    12 text {*
       
    13   The {\em Copying} TM, which duplicates its input. 
       
    14 *}
       
    15 
       
    16 definition tcopy_init :: "instr list"
       
    17 where
       
    18 "tcopy_init \<equiv> [(W0, 0), (R, 2), (R, 3), (R, 2),
       
    19                (W1, 3), (L, 4), (L, 4), (L, 0)]"
       
    20 
       
    21 fun inv_init1 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
    22   where
       
    23    "inv_init1 x (l, r) = (l = [] \<and> r = Oc\<up>x )"
       
    24 
       
    25 fun inv_init2 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
    26   where 
       
    27   "inv_init2 x (l, r) = (\<exists> i j. i > 0 \<and> i + j = x \<and> l = Oc\<up>i \<and> r = Oc\<up>j)"
       
    28 
       
    29 fun inv_init3 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
    30   where
       
    31   "inv_init3 x (l, r) = (x > 0 \<and> l = Bk # Oc\<up>x \<and> tl r = [])"
       
    32 
       
    33 fun inv_init4 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
    34   where
       
    35   "inv_init4 x (l, r) = (x > 0 \<and> ((l = Oc\<up>x \<and> r = [Bk, Oc]) \<or> (l = Oc\<up>(x - 1) \<and> r = [Oc, Bk, Oc])))"
       
    36 
       
    37 fun inv_init0 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
    38   where
       
    39   "inv_init0 x (l, r) = ((x >  Suc 0 \<and> l = Oc\<up>(x - 2) \<and> r = [Oc, Oc, Bk, Oc]) \<or>   
       
    40                         (x = 1 \<and> l = [] \<and> r = [Bk, Oc, Bk, Oc]))"
       
    41 
       
    42 fun inv_init :: "nat \<Rightarrow> config \<Rightarrow> bool"
       
    43   where
       
    44   "inv_init x (s, l, r) = (
       
    45          if s = 0 then inv_init0 x (l, r) 
       
    46          else if s = Suc 0 then inv_init1 x (l, r)
       
    47          else if s = 2 then inv_init2 x (l, r)
       
    48          else if s = 3 then inv_init3 x (l, r)
       
    49          else if s = 4 then inv_init4 x (l, r)
       
    50          else False)"
       
    51 
       
    52 declare inv_init.simps[simp del]
       
    53 
       
    54 lemma numeral_4_eq_4: "4 = Suc 3"
       
    55 by arith
       
    56 
       
    57 lemma [elim]: "\<lbrakk>0 < i; 0 < j\<rbrakk> \<Longrightarrow> 
       
    58   \<exists>ia>0. ia + j - Suc 0 = i + j \<and> Oc # Oc \<up> i = Oc \<up> ia"
       
    59 apply(rule_tac x = "Suc i" in exI, simp)
       
    60 done
       
    61 
       
    62 lemma inv_init_step: 
       
    63   "\<lbrakk>inv_init x cf; x > 0\<rbrakk>
       
    64  \<Longrightarrow> inv_init x (step cf (tcopy_init, 0))"
       
    65 apply(case_tac cf)
       
    66 apply(auto simp: inv_init.simps step.simps tcopy_init_def numeral_2_eq_2 
       
    67   numeral_3_eq_3 numeral_4_eq_4 split: if_splits)
       
    68 apply(case_tac "hd c", auto simp: inv_init.simps)
       
    69 apply(case_tac c, simp_all)
       
    70 done
       
    71 
       
    72 lemma inv_init_steps: 
       
    73   "\<lbrakk>inv_init x (s, l, r); x > 0\<rbrakk>
       
    74  \<Longrightarrow> inv_init x (steps (s, l, r) (tcopy_init, 0) stp)"
       
    75 apply(induct stp, simp add: steps.simps)
       
    76 apply(auto simp: step_red)
       
    77 apply(rule_tac inv_init_step, simp_all)
       
    78 done
       
    79 
       
    80 fun init_state :: "config \<Rightarrow> nat"
       
    81   where
       
    82   "init_state (s, l, r) = (if s = 0 then 0
       
    83                              else 5 - s)"
       
    84 
       
    85 fun init_step :: "config \<Rightarrow> nat"
       
    86   where
       
    87   "init_step (s, l, r) = (if s = 2 then length r
       
    88                             else if s = 3 then if r = [] \<or> r = [Bk] then Suc 0 else 0
       
    89                             else if s = 4 then length l
       
    90                             else 0)"
       
    91 
       
    92 fun init_measure :: "config \<Rightarrow> nat \<times> nat"
       
    93   where
       
    94   "init_measure c = 
       
    95    (init_state c, init_step c)"
       
    96 
       
    97 
       
    98 definition lex_pair :: "((nat \<times> nat) \<times> nat \<times> nat) set"
       
    99   where
       
   100   "lex_pair \<equiv> less_than <*lex*> less_than"
       
   101 
       
   102 definition init_LE :: "(config \<times> config) set"
       
   103   where
       
   104    "init_LE \<equiv> (inv_image lex_pair init_measure)"
       
   105 
       
   106 lemma [simp]: "\<lbrakk>tl r = []; r \<noteq> []; r \<noteq> [Bk]\<rbrakk> \<Longrightarrow> r = [Oc]"
       
   107 apply(case_tac r, auto, case_tac a, auto)
       
   108 done
       
   109 
       
   110 lemma wf_init_le: "wf init_LE"
       
   111 by(auto intro:wf_inv_image simp:init_LE_def lex_pair_def)
       
   112 
       
   113 lemma init_halt: 
       
   114   "x > 0 \<Longrightarrow> \<exists> stp. is_final (steps (Suc 0, [], Oc\<up>x) (tcopy_init, 0) stp)"
       
   115 proof(rule_tac LE = init_LE in halt_lemma)
       
   116   show "wf init_LE" by(simp add: wf_init_le)
       
   117 next
       
   118   assume h: "0 < x"
       
   119   show "\<forall>n. \<not> is_final (steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) n) \<longrightarrow>
       
   120         (steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) (Suc n), 
       
   121             steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) n) \<in> init_LE"
       
   122   proof(rule_tac allI, rule_tac impI)
       
   123     fix n
       
   124     assume a: "\<not> is_final (steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) n)"
       
   125     have b: "inv_init x (steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) n)"
       
   126       apply(rule_tac inv_init_steps)
       
   127       apply(simp_all add: inv_init.simps h)
       
   128       done 
       
   129     obtain s l r where c: "(steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) n) = (s, l, r)"
       
   130       apply(case_tac "steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) n", auto)
       
   131       done
       
   132     moreover hence "inv_init x (s, l, r)" 
       
   133       using c b by simp
       
   134     ultimately show "(steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) (Suc n), 
       
   135       steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) n) \<in> init_LE"
       
   136       using a 
       
   137     proof(simp)
       
   138       assume "inv_init x (s, l, r)" "0 < s"
       
   139       thus "(step (s, l, r) (tcopy_init, 0), s, l, r) \<in> init_LE"
       
   140         apply(auto simp: inv_init.simps init_LE_def lex_pair_def step.simps tcopy_init_def numeral_2_eq_2
       
   141           numeral_3_eq_3 numeral_4_eq_4 split: if_splits)
       
   142         apply(case_tac r, auto, case_tac a, auto)
       
   143         done
       
   144     qed
       
   145   qed
       
   146 qed
       
   147     
       
   148 lemma init_correct: 
       
   149   "x > 0 \<Longrightarrow> 
       
   150   {inv_init1 x} (tcopy_init, 0) {inv_init0 x}"
       
   151 proof(rule_tac HoareI)
       
   152   fix l r
       
   153   assume h: "0 < x"
       
   154     "inv_init1 x (l, r)"
       
   155   hence "\<exists> stp. is_final (steps (Suc 0, [], Oc\<up>x) (tcopy_init, 0) stp)"
       
   156     by(erule_tac init_halt)    
       
   157   then obtain stp where "is_final (steps (Suc 0, [], Oc\<up>x) (tcopy_init, 0) stp)" ..
       
   158   moreover have "inv_init x (steps (Suc 0, [], Oc\<up>x) (tcopy_init, 0) stp)"
       
   159     apply(rule_tac inv_init_steps)
       
   160     using h by(simp_all add: inv_init.simps)
       
   161   ultimately show
       
   162     "\<exists>n. is_final (steps (1, l, r) (tcopy_init, 0) n) \<and> 
       
   163     inv_init0 x holds_for steps (1, l, r) (tcopy_init, 0) n"
       
   164     using h
       
   165     apply(rule_tac x = stp in exI)
       
   166     apply(case_tac "(steps (Suc 0, [], Oc \<up> x) (tcopy_init, 0) stp)", simp add: inv_init.simps)
       
   167     done
       
   168 qed
       
   169 
       
   170 definition tcopy_loop :: "instr list"
       
   171 where
       
   172 "tcopy_loop \<equiv> [(R, 0), (R, 2),  (R, 3), (W0, 2),
       
   173                 (R, 3), (R, 4), (W1, 5), (R, 4),
       
   174                  (L, 6), (L, 5), (L, 6), (L, 1)]"
       
   175 
       
   176 fun inv_loop1_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   177   where
       
   178   "inv_loop1_loop x (l, r) = 
       
   179        (\<exists> i j. i + j + 1 = x \<and> l = Oc\<up>i \<and> r = Oc # Oc # Bk\<up>j @ Oc\<up>j \<and> j > 0)"
       
   180 
       
   181 fun inv_loop1_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   182   where
       
   183   "inv_loop1_exit x (l, r) = 
       
   184       (l = [] \<and> r = Bk # Oc # Bk\<up>x @ Oc\<up>x \<and> x > 0 )"
       
   185 
       
   186 fun inv_loop1 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   187   where
       
   188   "inv_loop1 x (l, r) = (inv_loop1_loop x (l, r) \<or> inv_loop1_exit x (l, r))"
       
   189 
       
   190 fun inv_loop2 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   191   where
       
   192   "inv_loop2 x (l, r) = 
       
   193        (\<exists> i j any. i + j = x \<and> x > 0 \<and> i > 0 \<and> j > 0 \<and> l = Oc\<up>i \<and> r = any#Bk\<up>j@Oc\<up>j)"
       
   194 
       
   195 fun inv_loop3 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   196   where
       
   197   "inv_loop3 x (l, r) = 
       
   198          (\<exists> i j k t. i + j = x \<and> i > 0 \<and> j > 0 \<and>  k + t = Suc j \<and> l = Bk\<up>k@Oc\<up>i \<and> r = Bk\<up>t@Oc\<up>j)"
       
   199 
       
   200 fun inv_loop4 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   201   where
       
   202   "inv_loop4 x (l, r) = 
       
   203            (\<exists> i j k t. i + j = x \<and> i > 0 \<and> j > 0 \<and>  k + t = j \<and> l = Oc\<up>k @ Bk\<up>(Suc j)@Oc\<up>i \<and> r = Oc\<up>t)"
       
   204 
       
   205 fun inv_loop5_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   206 where
       
   207   "inv_loop5_loop x (l, r) = 
       
   208           (\<exists> i j k t. i + j = Suc x \<and> i > 0 \<and> j > 0 \<and> k + t = j \<and> t > 0 \<and> l = Oc\<up>k@Bk\<up>j@Oc\<up>i \<and> r = Oc\<up>t)"
       
   209 
       
   210 fun inv_loop5_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   211   where
       
   212   "inv_loop5_exit x (l, r) = (\<exists> i j. i + j = Suc x \<and> i > 0 \<and> j > 0 \<and>  l = Bk\<up>(j - 1)@Oc\<up>i \<and> r = Bk # Oc\<up>j)"
       
   213 
       
   214 fun inv_loop5 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   215   where
       
   216   "inv_loop5 x (l, r) = (inv_loop5_loop x (l, r) \<or> 
       
   217                          inv_loop5_exit x (l, r))"
       
   218 
       
   219 fun inv_loop6_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   220   where
       
   221   "inv_loop6_loop x (l, r) = 
       
   222      (\<exists> i j k t. i + j = Suc x \<and> i > 0 \<and> k + t + 1 = j \<and> l = Bk\<up>k @ Oc\<up>i \<and> r = Bk\<up>(Suc t) @ Oc\<up>j)"
       
   223 
       
   224 fun inv_loop6_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   225   where
       
   226   "inv_loop6_exit x (l, r) = 
       
   227      (\<exists> i j. i + j = x \<and> j > 0 \<and> l = Oc\<up>i \<and> r = Oc # Bk\<up>j @ Oc\<up>j)"
       
   228 
       
   229 fun inv_loop6 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   230   where
       
   231   "inv_loop6 x (l, r) = (inv_loop6_loop x (l, r) \<or> inv_loop6_exit x (l, r))"
       
   232 
       
   233 fun inv_loop0 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   234   where
       
   235   "inv_loop0 x (l, r) = 
       
   236       (l = [Bk] \<and> r = Oc # Bk\<up>x @ Oc\<up>x \<and> x > 0 )"
       
   237 
       
   238 fun inv_loop :: "nat \<Rightarrow> config \<Rightarrow> bool"
       
   239   where
       
   240   "inv_loop x (s, l, r) = 
       
   241          (if s = 0 then inv_loop0 x (l, r)
       
   242           else if s = 1 then inv_loop1 x (l, r)
       
   243           else if s = 2 then inv_loop2 x (l, r)
       
   244           else if s = 3 then inv_loop3 x (l, r)
       
   245           else if s = 4 then inv_loop4 x (l, r)
       
   246           else if s = 5 then inv_loop5 x (l, r)
       
   247           else if s = 6 then inv_loop6 x (l, r)
       
   248           else False)"
       
   249        
       
   250 declare inv_loop.simps[simp del] inv_loop1.simps[simp del]
       
   251         inv_loop2.simps[simp del] inv_loop3.simps[simp del] 
       
   252         inv_loop4.simps[simp del] inv_loop5.simps[simp del] 
       
   253         inv_loop6.simps[simp del]
       
   254 lemma [elim]: "Bk # list = Oc \<up> t \<Longrightarrow> RR"
       
   255 apply(case_tac t, auto)
       
   256 done
       
   257 
       
   258 lemma numeral_5_eq_5: "5 = Suc 4" by arith
       
   259 
       
   260 lemma numeral_6_eq_6: "6 = Suc (Suc 4)" by arith
       
   261 
       
   262 lemma [simp]: "inv_loop1 x (b, []) = False"
       
   263 by(simp add: inv_loop1.simps)
       
   264 
       
   265 lemma [elim]: "\<lbrakk>0 < x; inv_loop2 x (b, [])\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, [])"
       
   266 apply(auto simp: inv_loop2.simps inv_loop3.simps)
       
   267 done
       
   268 
       
   269 lemma [elim]: "\<lbrakk>0 < x; inv_loop3 x (b, [])\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, [])"
       
   270 apply(auto simp: inv_loop3.simps)
       
   271 done
       
   272 
       
   273 lemma [elim]: "\<lbrakk>0 < x; inv_loop4 x (b, [])\<rbrakk> \<Longrightarrow> inv_loop5 x (b, [Oc])"
       
   274 apply(auto simp: inv_loop4.simps inv_loop5.simps)
       
   275 apply(rule_tac [!] x = i in exI, 
       
   276       rule_tac [!] x  = "Suc j" in exI, simp_all)
       
   277 done
       
   278 
       
   279 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x ([], [])\<rbrakk> \<Longrightarrow> RR"
       
   280 apply(auto simp: inv_loop4.simps inv_loop5.simps)
       
   281 done
       
   282 
       
   283 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x (b, []); b \<noteq> []\<rbrakk> \<Longrightarrow> RR"
       
   284 apply(auto simp: inv_loop4.simps inv_loop5.simps)
       
   285 done
       
   286 
       
   287 lemma [elim]: "inv_loop6 x ([], []) \<Longrightarrow> RR"
       
   288 apply(auto simp: inv_loop6.simps)
       
   289 done
       
   290 
       
   291 thm inv_loop6_exit.simps
       
   292 lemma [elim]: "inv_loop6 x (b, []) \<Longrightarrow> RR" 
       
   293 apply(auto simp: inv_loop6.simps)
       
   294 done
       
   295 
       
   296 lemma [elim]: "\<lbrakk>0 < x; inv_loop1 x (b, Bk # list)\<rbrakk> \<Longrightarrow> b = []"
       
   297 apply(auto simp: inv_loop1.simps)
       
   298 done
       
   299 
       
   300 lemma [elim]: "\<lbrakk>0 < x; inv_loop1 x (b, Bk # list)\<rbrakk> \<Longrightarrow> list = Oc # Bk \<up> x @ Oc \<up> x"
       
   301 apply(auto simp: inv_loop1.simps)
       
   302 done
       
   303 
       
   304 lemma [elim]: "\<lbrakk>0 < x; inv_loop2 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, list)"
       
   305 apply(auto simp: inv_loop2.simps inv_loop3.simps)
       
   306 apply(rule_tac [!] x = i  in exI, rule_tac [!] x = j in exI, simp_all)
       
   307 done
       
   308 
       
   309 lemma [elim]: "Bk # list = Oc \<up> j \<Longrightarrow> RR"
       
   310 apply(case_tac j, simp_all)
       
   311 done
       
   312 
       
   313 lemma [elim]: "\<lbrakk>0 < x; inv_loop3 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, list)"
       
   314 apply(auto simp: inv_loop3.simps)
       
   315 apply(rule_tac [!] x = i in exI, 
       
   316       rule_tac [!] x = j in exI, simp_all)
       
   317 apply(case_tac [!] t, auto)
       
   318 done
       
   319 
       
   320 lemma [elim]: "\<lbrakk>0 < x; inv_loop4 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_loop5 x (b, Oc # list)"
       
   321 apply(auto simp: inv_loop4.simps inv_loop5.simps)
       
   322 done
       
   323 
       
   324 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x ([], Bk # list)\<rbrakk> \<Longrightarrow> inv_loop6 x ([], Bk # Bk # list)"
       
   325 apply(auto simp: inv_loop6.simps inv_loop5.simps)
       
   326 done
       
   327 
       
   328 lemma [simp]: "inv_loop5_loop x (b, Bk # list) = False"
       
   329 apply(auto simp: inv_loop5_loop.simps)
       
   330 done
       
   331 
       
   332 lemma [simp]: "inv_loop6_exit x (b, Bk # list) = False"
       
   333 apply(auto simp: inv_loop6.simps)
       
   334 done
       
   335 
       
   336 declare inv_loop5_loop.simps[simp del]  inv_loop5_exit.simps[simp del]
       
   337        inv_loop6_loop.simps[simp del]  inv_loop6_exit.simps[simp del]
       
   338 
       
   339 lemma [elim]:"\<lbrakk>0 < x; inv_loop5_exit x (b, Bk # list); b \<noteq> []; hd b = Bk\<rbrakk> 
       
   340           \<Longrightarrow> inv_loop6_loop x (tl b, Bk # Bk # list)"
       
   341 apply(simp only: inv_loop5_exit.simps inv_loop6_loop.simps )
       
   342 apply(erule_tac exE)+
       
   343 apply(rule_tac x = i in exI, 
       
   344       rule_tac x = j in exI,
       
   345       rule_tac x = "j - Suc (Suc 0)" in exI, 
       
   346       rule_tac x = "Suc 0" in exI, auto)
       
   347 apply(case_tac [!] j, simp_all)
       
   348 apply(case_tac [!] nat, simp_all)
       
   349 done
       
   350 
       
   351 lemma [simp]: "inv_loop6_loop x (b, Oc # Bk # list) = False"
       
   352 apply(auto simp: inv_loop6_loop.simps)
       
   353 done
       
   354 
       
   355 lemma [elim]: "\<lbrakk>x > 0; inv_loop5_exit x (b, Bk # list); b \<noteq> []; hd b = Oc\<rbrakk> \<Longrightarrow> 
       
   356   inv_loop6_exit x (tl b, Oc # Bk # list)"
       
   357 apply(simp only: inv_loop5_exit.simps inv_loop6_exit.simps)
       
   358 apply(erule_tac exE)+
       
   359 apply(rule_tac x = "x - 1" in exI, rule_tac x = 1 in exI, simp)
       
   360 apply(case_tac j, auto)
       
   361 apply(case_tac [!] nat, auto)
       
   362 done
       
   363 
       
   364 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x (b, Bk # list); b \<noteq> []\<rbrakk> \<Longrightarrow> inv_loop6 x (tl b, hd b # Bk # list)"
       
   365 apply(simp add: inv_loop5.simps inv_loop6.simps)
       
   366 apply(case_tac "hd b", simp_all, auto)
       
   367 done
       
   368 
       
   369 lemma  [simp]: "inv_loop6 x ([], Bk # xs) = False"
       
   370 apply(simp add: inv_loop6.simps inv_loop6_loop.simps
       
   371                 inv_loop6_exit.simps)
       
   372 apply(auto)
       
   373 done
       
   374 
       
   375 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x ([], Bk # list)\<rbrakk> \<Longrightarrow> inv_loop6 x ([], Bk # Bk # list)"
       
   376 apply(simp)
       
   377 done
       
   378 
       
   379 lemma [simp]: "inv_loop6_exit x (b, Bk # list) = False"
       
   380 apply(simp add: inv_loop6_exit.simps)
       
   381 done
       
   382 
       
   383 lemma [elim]: "\<lbrakk>0 < x; inv_loop6_loop x (b, Bk # list); b \<noteq> []; hd b = Bk\<rbrakk>
       
   384               \<Longrightarrow> inv_loop6_loop x (tl b, Bk # Bk # list)"
       
   385 apply(simp only: inv_loop6_loop.simps)
       
   386 apply(erule_tac exE)+
       
   387 apply(rule_tac x = i in exI, rule_tac x = j in exI, 
       
   388       rule_tac x = "k - 1" in exI, rule_tac x = "Suc t" in exI, auto)
       
   389 apply(case_tac [!] k, auto)
       
   390 done
       
   391 
       
   392 lemma [elim]: "\<lbrakk>0 < x; inv_loop6_loop x (b, Bk # list); b \<noteq> []; hd b = Oc\<rbrakk> 
       
   393         \<Longrightarrow> inv_loop6_exit x (tl b, Oc # Bk # list)"
       
   394 apply(simp only: inv_loop6_loop.simps inv_loop6_exit.simps)
       
   395 apply(erule_tac exE)+
       
   396 apply(rule_tac x = "i - 1" in exI, rule_tac x = j in exI, auto)
       
   397 apply(case_tac [!] k, auto)
       
   398 done
       
   399 
       
   400 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x (b, Bk # list); b \<noteq> []\<rbrakk> \<Longrightarrow> inv_loop6 x (tl b, hd b # Bk # list)"
       
   401 apply(simp add: inv_loop6.simps)
       
   402 apply(case_tac "hd b", simp_all, auto)
       
   403 done
       
   404 
       
   405 lemma [elim]: "\<lbrakk>0 < x; inv_loop1 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop2 x (Oc # b, list)"
       
   406 apply(auto simp: inv_loop1.simps inv_loop2.simps)
       
   407 apply(rule_tac x = "Suc i" in exI, auto)
       
   408 done
       
   409 
       
   410 lemma [elim]: "\<lbrakk>0 < x; inv_loop2 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop2 x (b, Bk # list)"
       
   411 apply(auto simp: inv_loop2.simps)
       
   412 done
       
   413 
       
   414 lemma [elim]: "\<lbrakk>0 < x; inv_loop3 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop4 x (Oc # b, list)"
       
   415 apply(auto simp: inv_loop3.simps inv_loop4.simps)
       
   416 apply(rule_tac [!] x = i in exI, auto)
       
   417 apply(rule_tac [!] x = "Suc 0" in exI, rule_tac [!] x = "j - 1" in exI, auto)
       
   418 apply(case_tac [!] t, auto)
       
   419 apply(case_tac [!] j, auto)
       
   420 done
       
   421 
       
   422 lemma [elim]: "\<lbrakk>0 < x; inv_loop4 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop4 x (Oc # b, list)"
       
   423 apply(auto simp: inv_loop4.simps)
       
   424 apply(rule_tac [!] x = "i" in exI, auto)
       
   425 apply(rule_tac [!] x = "Suc k" in exI, rule_tac [!] x = "t - 1" in exI, auto)
       
   426 apply(case_tac [!] t, simp_all)
       
   427 done
       
   428 
       
   429 lemma [simp]: "inv_loop5 x ([], list) = False"
       
   430 apply(auto simp: inv_loop5.simps inv_loop5_exit.simps inv_loop5_loop.simps)
       
   431 done
       
   432 
       
   433 lemma [simp]: "inv_loop5_exit x (b, Oc # list) = False"
       
   434 apply(auto simp: inv_loop5_exit.simps)
       
   435 done
       
   436 
       
   437 lemma [elim]: " \<lbrakk>inv_loop5_loop x (b, Oc # list); b \<noteq> []; hd b = Bk\<rbrakk>
       
   438   \<Longrightarrow> inv_loop5_exit x (tl b, Bk # Oc # list)"
       
   439 apply(simp only: inv_loop5_loop.simps inv_loop5_exit.simps)
       
   440 apply(erule_tac exE)+
       
   441 apply(rule_tac x = i in exI, auto)
       
   442 apply(case_tac [!] k, auto)
       
   443 done
       
   444 
       
   445 lemma [elim]: "\<lbrakk>inv_loop5_loop x (b, Oc # list); b \<noteq> []; hd b = Oc\<rbrakk> 
       
   446            \<Longrightarrow> inv_loop5_loop x (tl b, Oc # Oc # list)"
       
   447 apply(simp only:  inv_loop5_loop.simps)
       
   448 apply(erule_tac exE)+
       
   449 apply(rule_tac x = i in exI, rule_tac x = j in exI)
       
   450 apply(rule_tac x = "k - 1" in exI, rule_tac x = "Suc t" in exI, auto)
       
   451 apply(case_tac [!] k, auto)
       
   452 done
       
   453 
       
   454 lemma [elim]: "\<lbrakk>inv_loop5 x (b, Oc # list); b \<noteq> []\<rbrakk> \<Longrightarrow> 
       
   455   inv_loop5 x (tl b, hd b # Oc # list)"
       
   456 apply(simp add: inv_loop5.simps)
       
   457 apply(case_tac "hd b", simp_all, auto)
       
   458 done
       
   459 
       
   460 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x ([], Oc # list)\<rbrakk> \<Longrightarrow> 
       
   461                inv_loop1 x ([], Bk # Oc # list)"
       
   462 apply(auto simp: inv_loop6.simps inv_loop1.simps 
       
   463   inv_loop6_loop.simps inv_loop6_exit.simps)
       
   464 done
       
   465 
       
   466 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x (b, Oc # list); b \<noteq> []\<rbrakk> 
       
   467            \<Longrightarrow> inv_loop1 x (tl b, hd b # Oc # list)"
       
   468 apply(auto simp: inv_loop6.simps inv_loop1.simps 
       
   469   inv_loop6_loop.simps inv_loop6_exit.simps)
       
   470 done
       
   471 
       
   472 lemma inv_loop_step: 
       
   473   "\<lbrakk>inv_loop x cf; x > 0\<rbrakk>
       
   474  \<Longrightarrow> inv_loop x (step cf (tcopy_loop, 0))"
       
   475 apply(case_tac cf, case_tac c, case_tac [2] aa)
       
   476 apply(auto simp: inv_loop.simps step.simps tcopy_loop_def numeral_2_eq_2  
       
   477   numeral_3_eq_3 numeral_4_eq_4 numeral_5_eq_5 numeral_6_eq_6 split: if_splits)
       
   478 done
       
   479 
       
   480 lemma inv_loop_steps:
       
   481   "\<lbrakk>inv_loop x cf; x > 0\<rbrakk>
       
   482   \<Longrightarrow> inv_loop x (steps cf (tcopy_loop, 0) stp)"
       
   483 apply(induct stp, simp add: steps.simps, simp)
       
   484 apply(erule_tac inv_loop_step, simp)
       
   485 done
       
   486 
       
   487 fun loop_stage :: "config \<Rightarrow> nat"
       
   488   where
       
   489   "loop_stage (s, l, r) = (if s = 0 then 0
       
   490                            else (Suc (length (takeWhile (\<lambda>a. a = Oc) (rev l @ r)))))"
       
   491 
       
   492 fun loop_state :: "config \<Rightarrow> nat"
       
   493   where
       
   494   "loop_state (s, l, r) = (if s = 2 \<and> hd r = Oc then 0
       
   495                            else if s = 1 then 1
       
   496                            else 10 - s)"
       
   497 
       
   498 fun loop_step :: "config \<Rightarrow> nat"
       
   499   where
       
   500   "loop_step (s, l, r) = (if s = 3 then length r
       
   501                           else if s = 4 then length r
       
   502                           else if s = 5 then length l 
       
   503                           else if s = 6 then length l
       
   504                           else 0)"
       
   505 
       
   506 definition lex_triple :: 
       
   507  "((nat \<times> (nat \<times> nat)) \<times> (nat \<times> (nat \<times> nat))) set"
       
   508   where
       
   509   "lex_triple \<equiv> less_than <*lex*> lex_pair"
       
   510 
       
   511 lemma wf_lex_triple: "wf lex_triple"
       
   512   by (auto intro:wf_lex_prod simp:lex_triple_def lex_pair_def)
       
   513 
       
   514 fun loop_measure :: "config \<Rightarrow> nat \<times> nat \<times> nat"
       
   515   where
       
   516   "loop_measure c = 
       
   517    (loop_stage c, loop_state c, loop_step c)"
       
   518 
       
   519 definition loop_LE :: "(config \<times> config) set"
       
   520   where
       
   521    "loop_LE \<equiv> (inv_image lex_triple loop_measure)"
       
   522 
       
   523 lemma wf_loop_le: "wf loop_LE"
       
   524 by(auto intro:wf_inv_image simp: loop_LE_def wf_lex_triple)
       
   525 
       
   526 lemma [simp]: "inv_loop2 x ([], b) = False"
       
   527 apply(auto simp: inv_loop2.simps)
       
   528 done
       
   529 
       
   530 lemma  [simp]: "inv_loop2 x (l', []) = False"
       
   531 apply(auto simp: inv_loop2.simps)
       
   532 done
       
   533 
       
   534 lemma [simp]: "inv_loop3 x (b, []) = False"
       
   535 apply(auto simp: inv_loop3.simps)
       
   536 done
       
   537 
       
   538 lemma [simp]: "inv_loop4 x ([], b) = False"
       
   539 apply(auto simp: inv_loop4.simps)
       
   540 done
       
   541 
       
   542 lemma [elim]: 
       
   543   "\<lbrakk>inv_loop4 x (l', []); l' \<noteq> []; x > 0;
       
   544   length (takeWhile (\<lambda>a. a = Oc) (rev l' @ [Oc])) \<noteq> 
       
   545   length (takeWhile (\<lambda>a. a = Oc) (rev l'))\<rbrakk>
       
   546   \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev l' @ [Oc])) < length (takeWhile (\<lambda>a. a = Oc) (rev l'))"
       
   547 apply(auto simp: inv_loop4.simps)
       
   548 apply(case_tac [!] j, simp_all add: List.takeWhile_tail)
       
   549 done
       
   550 
       
   551 
       
   552 lemma [elim]: 
       
   553   "\<lbrakk>inv_loop4 x (l', Bk # list); l' \<noteq> []; 0 < x;
       
   554    length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list)) \<noteq> 
       
   555     length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))\<rbrakk>
       
   556     \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list)) < 
       
   557     length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))"
       
   558 apply(auto simp: inv_loop4.simps)
       
   559 done
       
   560 
       
   561 lemma takeWhile_replicate_append: 
       
   562   "P a \<Longrightarrow> takeWhile P (a\<up>x @ ys) = a\<up>x @ takeWhile P ys"
       
   563 apply(induct x, auto)
       
   564 done
       
   565 
       
   566 lemma takeWhile_replicate: 
       
   567   "P a \<Longrightarrow> takeWhile P (a\<up>x) = a\<up>x"
       
   568 by(induct x, auto)
       
   569 
       
   570 lemma [elim]: 
       
   571    "\<lbrakk>inv_loop5 x (l', Bk # list); l' \<noteq> []; 0 < x;
       
   572    length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) \<noteq>
       
   573    length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))\<rbrakk>
       
   574    \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) < 
       
   575    length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))"
       
   576 apply(auto simp: inv_loop5.simps inv_loop5_exit.simps)
       
   577 apply(case_tac [!] j, simp_all)
       
   578 apply(case_tac [!] "nat", simp_all)
       
   579 apply(case_tac  nata, simp_all add: List.takeWhile_tail)
       
   580 apply(simp add: takeWhile_replicate_append takeWhile_replicate)
       
   581 apply(case_tac  nata, simp_all add: List.takeWhile_tail)
       
   582 done
       
   583 
       
   584 lemma [elim]: "\<lbrakk>inv_loop1 x (l', Oc # list)\<rbrakk> \<Longrightarrow> hd list = Oc"
       
   585 apply(auto simp: inv_loop1.simps)
       
   586 done
       
   587 
       
   588 lemma [elim]: 
       
   589   "\<lbrakk>inv_loop6 x (l', Bk # list); l' \<noteq> []; 0 < x;
       
   590   length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) \<noteq> 
       
   591   length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))\<rbrakk>
       
   592   \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) < 
       
   593   length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))"
       
   594 apply(auto simp: inv_loop6.simps)
       
   595 apply(case_tac l', simp_all)
       
   596 done
       
   597 
       
   598 lemma [elim]:
       
   599   "\<lbrakk>inv_loop2 x (l', Oc # list); l' \<noteq> []; 0 < x\<rbrakk> \<Longrightarrow> 
       
   600   length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list)) <
       
   601   length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))"
       
   602 apply(auto simp: inv_loop2.simps)
       
   603 apply(simp_all add: takeWhile_tail takeWhile_replicate_append
       
   604                 takeWhile_replicate)
       
   605 done
       
   606 
       
   607 lemma [elim]: 
       
   608   "\<lbrakk>inv_loop5 x (l', Oc # list); l' \<noteq> []; 0 < x;
       
   609   length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) \<noteq> 
       
   610   length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))\<rbrakk>
       
   611   \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) < 
       
   612   length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))"
       
   613 apply(auto simp: inv_loop5.simps)
       
   614 apply(case_tac l', auto)
       
   615 done
       
   616 
       
   617 
       
   618 lemma[elim]: 
       
   619   "\<lbrakk>inv_loop6 x (l', Oc # list); l' \<noteq> []; 0 < x;
       
   620   length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list))
       
   621   \<noteq> length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))\<rbrakk>
       
   622   \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) < 
       
   623       length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))"
       
   624 apply(case_tac l')
       
   625 apply(auto simp: inv_loop6.simps)
       
   626 done
       
   627 
       
   628 lemma loop_halt: 
       
   629   "\<lbrakk>x > 0; inv_loop x (Suc 0, l, r)\<rbrakk> \<Longrightarrow> 
       
   630       \<exists> stp. is_final (steps (Suc 0, l, r) (tcopy_loop, 0) stp)"
       
   631 proof(rule_tac LE = loop_LE in halt_lemma)
       
   632   show "wf loop_LE" by(intro wf_loop_le)
       
   633 next
       
   634   assume h: "0 < x"  and g: "inv_loop x (Suc 0, l, r)"
       
   635   show "\<forall>n. \<not> is_final (steps (Suc 0, l, r) (tcopy_loop, 0) n) \<longrightarrow> 
       
   636         (steps (Suc 0, l, r) (tcopy_loop, 0) (Suc n), steps (Suc 0, l, r) (tcopy_loop, 0) n) \<in> loop_LE"
       
   637   proof(rule_tac allI, rule_tac impI)
       
   638     fix n
       
   639     assume a: "\<not> is_final (steps (Suc 0, l, r) (tcopy_loop, 0) n)"
       
   640     obtain s' l' r' where d: "(steps (Suc 0, l, r) (tcopy_loop, 0) n) = (s', l', r')"
       
   641       by(case_tac "(steps (Suc 0, l, r) (tcopy_loop, 0) n)", auto)
       
   642     hence "inv_loop x (s', l', r') \<and> s' \<noteq> 0"
       
   643       using h g
       
   644       apply(drule_tac stp = n in inv_loop_steps, auto)
       
   645       using a
       
   646       apply(simp)
       
   647       done
       
   648     hence "(step(s', l', r') (tcopy_loop, 0), s', l', r') \<in> loop_LE"
       
   649       using h 
       
   650       apply(case_tac r', case_tac [2] a)
       
   651       apply(auto simp: inv_loop.simps step.simps tcopy_loop_def 
       
   652                        numeral_2_eq_2 numeral_3_eq_3 numeral_4_eq_4
       
   653                        numeral_5_eq_5 numeral_6_eq_6 loop_LE_def lex_triple_def lex_pair_def split: if_splits)
       
   654       done
       
   655     thus "(steps (Suc 0, l, r) (tcopy_loop, 0) (Suc n), 
       
   656           steps (Suc 0, l, r) (tcopy_loop, 0) n) \<in> loop_LE"
       
   657       using d
       
   658       apply(simp add: step_red)
       
   659       done
       
   660   qed
       
   661 qed
       
   662 
       
   663 lemma loop_correct:
       
   664   "x > 0 \<Longrightarrow> 
       
   665       {inv_loop1 x} (tcopy_loop, 0) {inv_loop0 x}"
       
   666 proof(rule_tac HoareI)
       
   667   fix l r
       
   668   assume h: "0 < x"
       
   669     "inv_loop1 x (l, r)"
       
   670   hence "\<exists> stp. is_final (steps (Suc 0, l, r) (tcopy_loop, 0) stp)"
       
   671     apply(rule_tac loop_halt, simp_all add: inv_loop.simps)
       
   672     done
       
   673   then obtain stp where "is_final (steps (Suc 0, l, r) (tcopy_loop, 0) stp)" ..
       
   674   moreover have "inv_loop x (steps (Suc 0, l, r) (tcopy_loop, 0) stp)"
       
   675     apply(rule_tac inv_loop_steps)
       
   676     using h by(simp_all add: inv_loop.simps)
       
   677   ultimately show
       
   678     "\<exists>n. is_final (steps (1, l, r) (tcopy_loop, 0) n) \<and> 
       
   679     inv_loop0 x holds_for steps (1, l, r) (tcopy_loop, 0) n"    
       
   680     using h
       
   681     apply(rule_tac x = stp in exI)
       
   682     apply(case_tac "(steps (Suc 0, l, r) (tcopy_loop, 0) stp)", 
       
   683       simp add: inv_init.simps inv_loop.simps)
       
   684     done
       
   685 qed
       
   686   
       
   687 definition tcopy_end :: "instr list"
       
   688   where
       
   689   "tcopy_end \<equiv> [(L, 0), (R, 2), (W1, 3), (L, 4),
       
   690                 (R, 2), (R, 2), (L, 5), (W0, 4),
       
   691                 (R, 0), (L, 5)]"
       
   692 
       
   693 fun inv_end1 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   694   where
       
   695   "inv_end1 x (l, r) = (x > 0 \<and> l = [Bk] \<and> r = Oc # Bk\<up>x @ Oc\<up>x)"
       
   696 
       
   697 fun inv_end2 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   698   where
       
   699   "inv_end2 x (l, r) = (\<exists> i j. i + j = Suc x \<and> x > 0 \<and> l = Oc\<up>i @ [Bk] \<and> r = Bk\<up>j @ Oc\<up>)"
       
   700 
       
   701 fun inv_end3 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   702   where
       
   703   "inv_end3 x (l, r) =
       
   704         (\<exists> i j. x > 0 \<and> i + j = x \<and> l = Oc\<up>i @ [Bk] \<and> r = Oc # Bk\<up>j@ Oc\<up>x )"
       
   705 
       
   706 fun inv_end4 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   707   where
       
   708   "inv_end4 x (l, r) = (\<exists> any. x > 0 \<and> l = Oc\<up>x @ [Bk] \<and> r = any#Oc\<up>x)"
       
   709 
       
   710 fun inv_end5_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   711   where
       
   712   "inv_end5_loop x (l, r) = 
       
   713          (\<exists> i j. i + j = x \<and> x > 0 \<and> j > 0 \<and> l = Oc\<up>i @ [Bk] \<and> r = Oc\<up>j @ Bk # Oc\<up>x)"
       
   714 
       
   715 fun inv_end5_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   716   where
       
   717   "inv_end5_exit x (l, r) = (x > 0 \<and> l = [] \<and> r = Bk # Oc\<up>x @ Bk # Oc\<up>x)"
       
   718 
       
   719 fun inv_end5 :: "nat \<Rightarrow> tape \<Rightarrow> bool"
       
   720   where
       
   721   "inv_end5 x (l, r) = (inv_end5_loop x (l, r) \<or> inv_end5_exit x (l, r))"
       
   722 
       
   723 fun inv_end0 :: "nat \<Rightarrow> tape \<Rightarrow>  bool"
       
   724   where
       
   725   "inv_end0 x (l, r) = (x > 0 \<and> l = [Bk] \<and> r = Oc\<up>x @ Bk # Oc\<up>x)"
       
   726 
       
   727 fun inv_end :: "nat \<Rightarrow> config \<Rightarrow> bool"
       
   728   where
       
   729   "inv_end x (s, l, r) = (if s = 0 then inv_end0 x (l, r)
       
   730                           else if s = 1 then inv_end1 x (l, r)
       
   731                           else if s = 2 then inv_end2 x (l, r)
       
   732                           else if s = 3 then inv_end3 x (l, r)
       
   733                           else if s = 4 then inv_end4 x (l, r)
       
   734                           else if s = 5 then inv_end5 x (l, r)
       
   735                           else False)"
       
   736 
       
   737 declare inv_end.simps[simp del] inv_end1.simps[simp del]
       
   738         inv_end0.simps[simp del] inv_end2.simps[simp del]
       
   739         inv_end3.simps[simp del] inv_end4.simps[simp del]
       
   740         inv_end5.simps[simp del]
       
   741 
       
   742 lemma [simp]:  "inv_end1 x (b, []) = False"
       
   743 apply(auto simp: inv_end1.simps)
       
   744 done
       
   745 
       
   746 lemma [simp]: "inv_end2 x (b, []) = False"
       
   747 apply(auto simp: inv_end2.simps)
       
   748 done
       
   749 
       
   750 lemma [simp]: "inv_end3 x (b, []) = False"
       
   751 apply(auto simp: inv_end3.simps)
       
   752 done
       
   753 
       
   754 thm inv_end4.simps
       
   755 lemma [simp]: "inv_end4 x (b, []) = False"
       
   756 apply(auto simp: inv_end4.simps)
       
   757 done
       
   758 
       
   759 lemma [simp]: "inv_end5 x (b, []) = False"
       
   760 apply(auto simp: inv_end5.simps)
       
   761 done
       
   762 
       
   763 lemma [simp]: "inv_end1 x ([], list) = False"
       
   764 apply(auto simp: inv_end1.simps)
       
   765 done
       
   766 
       
   767 lemma [elim]: "\<lbrakk>0 < x; inv_end1 x (b, Bk # list); b \<noteq> []\<rbrakk>
       
   768   \<Longrightarrow> inv_end0 x (tl b, hd b # Bk # list)"
       
   769 apply(auto simp: inv_end1.simps inv_end0.simps)
       
   770 done
       
   771 
       
   772 lemma [elim]: "\<lbrakk>0 < x; inv_end2 x (b, Bk # list)\<rbrakk> 
       
   773   \<Longrightarrow> inv_end3 x (b, Oc # list)"
       
   774 apply(auto simp: inv_end2.simps inv_end3.simps)
       
   775 apply(rule_tac x = "j - 1" in exI)
       
   776 apply(case_tac j, simp_all)
       
   777 apply(case_tac x, simp_all)
       
   778 done
       
   779 
       
   780 lemma [elim]: "\<lbrakk>0 < x; inv_end3 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_end2 x (Bk # b, list)"
       
   781 apply(auto simp: inv_end2.simps inv_end3.simps)
       
   782 done
       
   783   
       
   784 lemma [elim]: "\<lbrakk>0 < x; inv_end4 x ([], Bk # list)\<rbrakk> \<Longrightarrow> 
       
   785   inv_end5 x ([], Bk # Bk # list)"
       
   786 apply(auto simp: inv_end4.simps inv_end5.simps)
       
   787 done
       
   788  
       
   789 lemma [elim]: "\<lbrakk>0 < x; inv_end4 x (b, Bk # list); b \<noteq> []\<rbrakk> \<Longrightarrow> 
       
   790   inv_end5 x (tl b, hd b # Bk # list)"
       
   791 apply(auto simp: inv_end4.simps inv_end5.simps)
       
   792 apply(rule_tac x = 1 in exI, simp)
       
   793 done
       
   794 
       
   795 lemma [elim]: "\<lbrakk>0 < x; inv_end5 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_end0 x (Bk # b, list)"
       
   796 apply(auto simp: inv_end5.simps inv_end0.simps)
       
   797 apply(case_tac [!] j, simp_all)
       
   798 done
       
   799 
       
   800 lemma [elim]: "\<lbrakk>0 < x; inv_end1 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_end2 x (Oc # b, list)"
       
   801 apply(auto simp: inv_end1.simps inv_end2.simps)
       
   802 done
       
   803 
       
   804 lemma [elim]: "\<lbrakk>0 < x; inv_end2 x ([], Oc # list)\<rbrakk> \<Longrightarrow>
       
   805                inv_end4 x ([], Bk # Oc # list)"
       
   806 apply(auto simp: inv_end2.simps inv_end4.simps)
       
   807 done
       
   808 
       
   809 lemma [elim]:  "\<lbrakk>0 < x; inv_end2 x (b, Oc # list); b \<noteq> []\<rbrakk> \<Longrightarrow>
       
   810   inv_end4 x (tl b, hd b # Oc # list)"
       
   811 apply(auto simp: inv_end2.simps inv_end4.simps)
       
   812 apply(case_tac [!] j, simp_all)
       
   813 done
       
   814 
       
   815 lemma [elim]: "\<lbrakk>0 < x; inv_end3 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_end2 x (Oc # b, list)"
       
   816 apply(auto simp: inv_end2.simps inv_end3.simps)
       
   817 done
       
   818 
       
   819 lemma [elim]: "\<lbrakk>0 < x; inv_end4 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_end4 x (b, Bk # list)"
       
   820 apply(auto simp: inv_end2.simps inv_end4.simps)
       
   821 done
       
   822 
       
   823 lemma [elim]: "\<lbrakk>0 < x; inv_end5 x ([], Oc # list)\<rbrakk> \<Longrightarrow> inv_end5 x ([], Bk # Oc # list)"
       
   824 apply(auto simp: inv_end2.simps inv_end5.simps)
       
   825 done
       
   826 
       
   827 declare inv_end5_loop.simps[simp del]
       
   828         inv_end5_exit.simps[simp del]
       
   829 
       
   830 lemma [simp]: "inv_end5_exit x (b, Oc # list) = False"
       
   831 apply(auto simp: inv_end5_exit.simps)
       
   832 done
       
   833 
       
   834 lemma [simp]: "inv_end5_loop x (tl b, Bk # Oc # list) = False"
       
   835 apply(auto simp: inv_end5_loop.simps)
       
   836 apply(case_tac [!] j, simp_all)
       
   837 done
       
   838 
       
   839 lemma [elim]:
       
   840   "\<lbrakk>0 < x; inv_end5_loop x (b, Oc # list); b \<noteq> []; hd b = Bk\<rbrakk> \<Longrightarrow>
       
   841   inv_end5_exit x (tl b, Bk # Oc # list)"
       
   842 apply(auto simp: inv_end5_loop.simps inv_end5_exit.simps)
       
   843 apply(case_tac [!] i, simp_all)
       
   844 done
       
   845 
       
   846 lemma [elim]: 
       
   847   "\<lbrakk>0 < x; inv_end5_loop x (b, Oc # list); b \<noteq> []; hd b = Oc\<rbrakk> \<Longrightarrow>
       
   848   inv_end5_loop x (tl b, Oc # Oc # list)"
       
   849 apply(simp only: inv_end5_loop.simps inv_end5_exit.simps)
       
   850 apply(erule_tac exE)+
       
   851 apply(rule_tac x = "i - 1" in exI, 
       
   852       rule_tac x = "Suc j" in exI, auto)
       
   853 apply(case_tac [!] i, simp_all)
       
   854 done
       
   855 
       
   856 lemma [elim]: "\<lbrakk>0 < x; inv_end5 x (b, Oc # list); b \<noteq> []\<rbrakk> \<Longrightarrow> 
       
   857   inv_end5 x (tl b, hd b # Oc # list)"
       
   858 apply(simp add: inv_end2.simps inv_end5.simps)
       
   859 apply(case_tac "hd b", simp_all, auto)
       
   860 done
       
   861 
       
   862 lemma inv_end_step:
       
   863   "\<lbrakk>x > 0;
       
   864  inv_end x cf\<rbrakk>
       
   865  \<Longrightarrow> inv_end x (step cf (tcopy_end, 0))"
       
   866 apply(case_tac cf, case_tac c, case_tac [2] aa)
       
   867 apply(auto simp: inv_end.simps step.simps tcopy_end_def numeral_2_eq_2 
       
   868   numeral_3_eq_3 numeral_4_eq_4 numeral_5_eq_5 split: if_splits)
       
   869 done
       
   870 
       
   871 lemma inv_end_steps:
       
   872   "\<lbrakk>x > 0; inv_end x cf\<rbrakk>
       
   873 \<Longrightarrow> inv_end x (steps cf (tcopy_end, 0) stp)"
       
   874 apply(induct stp, simp add:steps.simps, simp)
       
   875 apply(erule_tac inv_end_step, simp)
       
   876 done
       
   877 
       
   878 fun end_state :: "config \<Rightarrow> nat"
       
   879   where
       
   880   "end_state (s, l, r) = 
       
   881        (if s = 0 then 0
       
   882         else if s = 1 then 5
       
   883         else if s = 2 \<or> s = 3 then 4
       
   884         else if s = 4 then 3 
       
   885         else if s = 5 then 2
       
   886         else 0)"
       
   887 
       
   888 fun end_stage :: "config \<Rightarrow> nat"
       
   889   where
       
   890   "end_stage (s, l, r) = 
       
   891           (if s = 2 \<or> s = 3 then (length r)
       
   892            else 0)"
       
   893 
       
   894 fun end_step :: "config \<Rightarrow> nat"
       
   895   where
       
   896   "end_step (s, l, r) = 
       
   897          (if s = 4 then (if hd r = Oc then 1 else 0)
       
   898           else if s = 5 then length l
       
   899           else if s = 2 then 1
       
   900           else if s = 3 then 0
       
   901           else 0)"
       
   902 
       
   903 fun end_measure :: "config \<Rightarrow> nat \<times> nat \<times> nat"
       
   904   where
       
   905   "end_measure c = 
       
   906    (end_state c, end_stage c, end_step c)"
       
   907 
       
   908 definition end_LE :: "(config \<times> config) set"
       
   909   where
       
   910    "end_LE \<equiv> (inv_image lex_triple end_measure)"
       
   911 
       
   912 lemma wf_end_le: "wf end_LE"
       
   913 by(auto intro:wf_inv_image simp: end_LE_def wf_lex_triple)
       
   914 
       
   915 lemma [simp]: "inv_end5 x ([], Oc # list) = False"
       
   916 apply(auto simp: inv_end5.simps inv_end5_loop.simps)
       
   917 done
       
   918 
       
   919 lemma end_halt: 
       
   920   "\<lbrakk>x > 0; inv_end x (Suc 0, l, r)\<rbrakk> \<Longrightarrow> 
       
   921       \<exists> stp. is_final (steps (Suc 0, l, r) (tcopy_end, 0) stp)"
       
   922 proof(rule_tac LE = end_LE in halt_lemma)
       
   923   show "wf end_LE" by(intro wf_end_le)
       
   924 next
       
   925   assume great: "0 < x"
       
   926     and inv_start: "inv_end x (Suc 0, l, r)"
       
   927   show "\<forall>n. \<not> is_final (steps (Suc 0, l, r) (tcopy_end, 0) n) \<longrightarrow> 
       
   928     (steps (Suc 0, l, r) (tcopy_end, 0) (Suc n), steps (Suc 0, l, r) (tcopy_end, 0) n) \<in> end_LE"
       
   929   proof(rule_tac allI, rule_tac impI)
       
   930     fix n
       
   931     assume notfinal: "\<not> is_final (steps (Suc 0, l, r) (tcopy_end, 0) n)"
       
   932     obtain s' l' r' where d: "steps (Suc 0, l, r) (tcopy_end, 0) n = (s', l', r')"
       
   933       apply(case_tac "steps (Suc 0, l, r) (tcopy_end, 0) n", auto)
       
   934       done
       
   935     hence "inv_end x (s', l', r') \<and> s' \<noteq> 0"
       
   936       using great inv_start notfinal
       
   937       apply(drule_tac stp = n in inv_end_steps, auto)
       
   938       done
       
   939     hence "(step (s', l', r') (tcopy_end, 0), s', l', r') \<in> end_LE"
       
   940       apply(case_tac r', case_tac [2] a)
       
   941       apply(auto simp: inv_end.simps step.simps tcopy_end_def 
       
   942                        numeral_2_eq_2 numeral_3_eq_3 numeral_4_eq_4 
       
   943                        numeral_5_eq_5 numeral_6_eq_6 end_LE_def lex_triple_def lex_pair_def split: if_splits)
       
   944       done
       
   945     thus "(steps (Suc 0, l, r) (tcopy_end, 0) (Suc n), 
       
   946       steps (Suc 0, l, r) (tcopy_end, 0) n) \<in> end_LE"
       
   947       using d
       
   948       by simp
       
   949   qed
       
   950 qed
       
   951 
       
   952 lemma end_correct:
       
   953   "x > 0 \<Longrightarrow> 
       
   954       {inv_end1 x} (tcopy_end, 0) {inv_end0 x}"
       
   955 proof(rule_tac HoareI)
       
   956   fix l r
       
   957   assume h: "0 < x"
       
   958     "inv_end1 x (l, r)"
       
   959   hence "\<exists> stp. is_final (steps (Suc 0, l, r) (tcopy_end, 0) stp)"
       
   960     apply(rule_tac end_halt, simp_all add: inv_end.simps)
       
   961     done
       
   962   then obtain stp where "is_final (steps (Suc 0, l, r) (tcopy_end, 0) stp)" ..
       
   963   moreover have "inv_end x (steps (Suc 0, l, r) (tcopy_end, 0) stp)"
       
   964     apply(rule_tac inv_end_steps)
       
   965     using h by(simp_all add: inv_end.simps)
       
   966   ultimately show
       
   967     "\<exists>n. is_final (steps (1, l, r) (tcopy_end, 0) n) \<and> 
       
   968     inv_end0 x holds_for steps (1, l, r) (tcopy_end, 0) n"        
       
   969     using h
       
   970     apply(rule_tac x = stp in exI)
       
   971     apply(case_tac "(steps (Suc 0, l, r) (tcopy_end, 0) stp)", 
       
   972       simp add:  inv_end.simps)
       
   973     done
       
   974 qed
       
   975 
       
   976 definition tcopy :: "instr list"
       
   977   where
       
   978   "tcopy = ((tcopy_init |+| tcopy_loop) |+| tcopy_end)"
       
   979 
       
   980 lemma [intro]: "tm_wf (tcopy_init, 0)"
       
   981 by(auto simp: tm_wf.simps tcopy_init_def)
       
   982 
       
   983 lemma [intro]: "tm_wf (tcopy_loop, 0)"
       
   984 by(auto simp: tm_wf.simps tcopy_loop_def)
       
   985 
       
   986 lemma [intro]: "tm_wf (tcopy_end, 0)"
       
   987 by(auto simp: tm_wf.simps tcopy_end_def)
       
   988 
       
   989 lemma [intro]: "\<lbrakk>tm_wf (A, 0); tm_wf (B, 0)\<rbrakk> \<Longrightarrow> tm_wf (A |+| B, 0)"
       
   990 apply(auto simp: tm_wf.simps shift.simps adjust.simps length_comp
       
   991                  tm_comp.simps)
       
   992 done
       
   993 
       
   994 lemma tcopy_correct1: 
       
   995   "\<lbrakk>x > 0\<rbrakk> \<Longrightarrow> {inv_init1 x} (tcopy, 0) {inv_end0 x}"
       
   996 proof(simp add: tcopy_def, rule_tac Hoare_plus_halt)
       
   997   show "inv_loop0 x \<mapsto> inv_end1 x"
       
   998     by(auto simp: inv_end1.simps inv_loop1.simps assert_imp_def)
       
   999 next
       
  1000   show "tm_wf (tcopy_init |+| tcopy_loop, 0)" by auto
       
  1001 next
       
  1002   show "tm_wf (tcopy_end, 0)" by auto
       
  1003 next
       
  1004   assume "0 < x"
       
  1005   thus "{inv_init1 x} (tcopy_init |+| tcopy_loop, 0) {inv_loop0 x}"
       
  1006   proof(rule_tac Hoare_plus_halt)
       
  1007     show "inv_init0 x \<mapsto> inv_loop1 x"
       
  1008       apply(auto simp: inv_init0.simps inv_loop1.simps assert_imp_def)
       
  1009       apply(rule_tac x = "Suc 0" in exI, auto)
       
  1010       done
       
  1011   next
       
  1012     show "tm_wf (tcopy_init, 0)" by auto
       
  1013   next
       
  1014     show "tm_wf (tcopy_loop, 0)" by auto
       
  1015   next
       
  1016     assume "0 < x"
       
  1017     thus "{inv_init1 x} (tcopy_init, 0) {inv_init0 x}"
       
  1018       by(erule_tac init_correct)
       
  1019   next
       
  1020     assume "0 < x"
       
  1021     thus "{inv_loop1 x} (tcopy_loop, 0) {inv_loop0 x}"
       
  1022       by(erule_tac loop_correct)
       
  1023   qed
       
  1024 next
       
  1025   assume "0 < x"
       
  1026   thus "{inv_end1 x} (tcopy_end, 0) {inv_end0 x}"
       
  1027     by(erule_tac end_correct)
       
  1028 qed
       
  1029 
       
  1030 section {*
       
  1031   The {\em Dithering} Turing Machine 
       
  1032 *}
       
  1033 
       
  1034 text {*
       
  1035   The {\em Dithering} TM, when the input is @{text "1"}, it will loop forever, otherwise, it will
       
  1036   terminate.
       
  1037 *}
       
  1038 definition dither :: "instr list"
       
  1039   where
       
  1040   "dither \<equiv> [(W0, 1), (R, 2), (L, 1), (L, 0)] "
       
  1041 
       
  1042 lemma dither_halt_rs: 
       
  1043   "\<exists> stp. steps (Suc 0, Bk\<up>m, [Oc, Oc]) (dither, 0) stp = 
       
  1044                                  (0, Bk\<up>m, [Oc, Oc])"
       
  1045 apply(rule_tac x = "Suc (Suc (Suc 0))" in exI)
       
  1046 apply(simp add: dither_def steps.simps 
       
  1047                 step.simps fetch.simps numeral_2_eq_2)
       
  1048 done
       
  1049 
       
  1050 lemma dither_unhalt_state: 
       
  1051   "(steps (Suc 0, Bk\<up>m, [Oc]) (dither, 0) stp = 
       
  1052    (Suc 0, Bk\<up>m, [Oc])) \<or> 
       
  1053    (steps (Suc 0, Bk\<up>m, [Oc]) (dither, 0) stp = (2, Oc # Bk\<up>m, []))"
       
  1054   apply(induct stp, simp add: steps.simps)
       
  1055   apply(simp add: step_red, auto)
       
  1056   apply(auto simp: step.simps fetch.simps dither_def numeral_2_eq_2)
       
  1057   done
       
  1058 
       
  1059 lemma dither_unhalt_rs: 
       
  1060   "\<not> is_final (steps (Suc 0, Bk\<up>m, [Oc]) (dither,0) stp)"
       
  1061 using dither_unhalt_state[of m stp]
       
  1062 apply(auto)
       
  1063 done
       
  1064 
       
  1065 section {*
       
  1066   The final diagnal arguments to show the undecidability of Halting problem.
       
  1067 *}
       
  1068 
       
  1069 text {*
       
  1070   @{text "haltP tp x"} means TM @{text "tp"} terminates on input @{text "x"}
       
  1071   and the final configuration is standard.
       
  1072 *}
       
  1073 
       
  1074 
       
  1075 fun tape_of_nat_list :: "nat list \<Rightarrow> cell list" ("< _ >" [0] 100)
       
  1076   where 
       
  1077   "tape_of_nat_list [] = []" |
       
  1078   "tape_of_nat_list [n] = Oc\<up>(Suc n)" |
       
  1079   "tape_of_nat_list (n#ns) = Oc\<up>(Suc n) @ Bk # (tape_of_nat_list ns)"
       
  1080 
       
  1081 definition haltP :: "tprog \<Rightarrow> nat list \<Rightarrow> bool"
       
  1082   where
       
  1083   "haltP t lm = (\<exists>n a b c. steps (Suc 0, [], <lm>) t n = (0, Bk\<up>a,  Oc\<up>b @ Bk\<up>c))"
       
  1084 
       
  1085 lemma [intro]: "tm_wf (tcopy, 0)"
       
  1086 by(auto simp: tcopy_def)
       
  1087 
       
  1088 lemma [intro]: "tm_wf (dither, 0)"
       
  1089 apply(auto simp: tm_wf.simps dither_def)
       
  1090 done
       
  1091 
       
  1092 text {*
       
  1093   The following lemma shows the meaning of @{text "tinres"} with respect to 
       
  1094   one step execution.
       
  1095   *}
       
  1096 lemma tinres_step: 
       
  1097   "\<lbrakk>tinres l l'; step (ss, l, r) (t, 0) = (sa, la, ra); 
       
  1098                  step (ss, l', r) (t, 0) = (sb, lb, rb)\<rbrakk>
       
  1099     \<Longrightarrow> tinres la lb \<and> ra = rb \<and> sa = sb"
       
  1100 apply(case_tac ss, case_tac [!]r, case_tac [!] "a::cell")
       
  1101 apply(auto simp: step.simps fetch.simps
       
  1102         split: if_splits )
       
  1103 apply(case_tac [!] "t ! (2 * nat)", 
       
  1104      auto simp: tinres_def split: if_splits)
       
  1105 apply(case_tac [1-8] a, auto split: if_splits)
       
  1106 apply(case_tac [!] "t ! (2 * nat)", 
       
  1107      auto simp: tinres_def split: if_splits)
       
  1108 apply(case_tac [1-4] a, auto split: if_splits)
       
  1109 apply(case_tac [!] "t ! Suc (2 * nat)", 
       
  1110      auto simp: if_splits)
       
  1111 apply(case_tac [!] aa, auto split: if_splits)
       
  1112 done
       
  1113 
       
  1114 text {*
       
  1115   The following lemma shows the meaning of @{text "tinres"} with respect to 
       
  1116   many step execution.
       
  1117   *}
       
  1118 
       
  1119 lemma tinres_steps: 
       
  1120   "\<lbrakk>tinres l l'; steps (ss, l, r) (t, 0) stp = (sa, la, ra); 
       
  1121                  steps (ss, l', r) (t, 0) stp = (sb, lb, rb)\<rbrakk>
       
  1122     \<Longrightarrow> tinres la lb \<and> ra = rb \<and> sa = sb"
       
  1123 apply(induct stp arbitrary: sa la ra sb lb rb, simp add: steps.simps)
       
  1124 apply(simp add: step_red)
       
  1125 apply(case_tac "(steps (ss, l, r) (t, 0) stp)")
       
  1126 apply(case_tac "(steps (ss, l', r) (t, 0) stp)")
       
  1127 proof -
       
  1128   fix stp sa la ra sb lb rb a b c aa ba ca
       
  1129   assume ind: "\<And>sa la ra sb lb rb. \<lbrakk>steps (ss, l, r) (t, 0) stp = (sa, (la::cell list), ra); 
       
  1130           steps (ss, l', r) (t, 0) stp = (sb, lb, rb)\<rbrakk> \<Longrightarrow> tinres la lb \<and> ra = rb \<and> sa = sb"
       
  1131   and h: " tinres l l'" "step (steps (ss, l, r) (t, 0) stp) (t, 0) = (sa, la, ra)"
       
  1132          "step (steps (ss, l', r) (t, 0) stp) (t, 0) = (sb, lb, rb)" "steps (ss, l, r) (t, 0) stp = (a, b, c)" 
       
  1133          "steps (ss, l', r) (t, 0) stp = (aa, ba, ca)"
       
  1134   have "tinres b ba \<and> c = ca \<and> a = aa"
       
  1135     apply(rule_tac ind, simp_all add: h)
       
  1136     done
       
  1137   thus "tinres la lb \<and> ra = rb \<and> sa = sb"
       
  1138     apply(rule_tac l = b and l' = ba and r = c  and ss = a   
       
  1139             and t = t in tinres_step)
       
  1140     using h
       
  1141     apply(simp, simp, simp)
       
  1142     done
       
  1143 qed
       
  1144 
       
  1145 lemma length_eq: "xs = ys \<Longrightarrow> length xs = length ys"
       
  1146 by auto
       
  1147 
       
  1148 lemma tinres_ex1: "tinres (Bk \<up> nb) b \<Longrightarrow> \<exists>nb. b = Bk \<up> nb"
       
  1149 apply(auto simp: tinres_def replicate_add[THEN sym])
       
  1150 apply(case_tac "nb \<ge> n")
       
  1151 apply(subgoal_tac "\<exists> d. nb = d + n", auto simp: replicate_add)
       
  1152 apply arith
       
  1153 apply(drule_tac length_eq, simp)
       
  1154 done
       
  1155 
       
  1156 lemma Hoare_weak:
       
  1157   "\<lbrakk>{P} (p, off) {Q}; P'\<mapsto>P; Q\<mapsto>Q'\<rbrakk> \<Longrightarrow> {P'} (p, off) {Q'}"
       
  1158 using Hoare_def
       
  1159 proof(auto simp: assert_imp_def)
       
  1160   fix l r
       
  1161   assume 
       
  1162     ho1: "\<forall>l r. P (l, r) \<longrightarrow> (\<exists>n. is_final (steps (Suc 0, l, r) (p, off) n) 
       
  1163     \<and> Q holds_for steps (Suc 0, l, r) (p, off) n)"
       
  1164     and imp1: "\<forall>l r. P' (l, r) \<longrightarrow> P (l, r)"
       
  1165     and imp2: "\<forall>l r. Q (l, r) \<longrightarrow> Q' (l, r)"
       
  1166     and cond: "P' (l, r)"
       
  1167     and ho2: "\<And>P a b Q. {P} (a, b) {Q} \<equiv> \<forall>l r. P (l, r) \<longrightarrow>
       
  1168     (\<exists>n. is_final (steps (Suc 0, l, r) (a, b) n) \<and> Q holds_for steps (Suc 0, l, r) (a, b) n)"
       
  1169   have "P (l, r)"
       
  1170     using cond imp1 by auto
       
  1171   hence "(\<exists>n. is_final (steps (Suc 0, l, r) (p, off) n) 
       
  1172     \<and> Q holds_for steps (Suc 0, l, r) (p, off) n)"
       
  1173     using ho1 by auto
       
  1174   from this obtain n where "is_final (steps (Suc 0, l, r) (p, off) n) 
       
  1175     \<and> Q holds_for steps (Suc 0, l, r) (p, off) n" ..
       
  1176   thus "\<exists>n. is_final (steps (Suc 0, l, r) (p, off) n) \<and> 
       
  1177     Q' holds_for steps (Suc 0, l, r) (p, off) n"
       
  1178     apply(rule_tac x = n in exI, auto)
       
  1179     apply(case_tac "steps (Suc 0, l, r) (p, off) n", simp)
       
  1180     using imp2
       
  1181     by simp
       
  1182 qed
       
  1183 
       
  1184 text {*
       
  1185   The following locale specifies that TM @{text "H"} can be used to solve 
       
  1186   the {\em Halting Problem} and @{text "False"} is going to be derived 
       
  1187   under this locale. Therefore, the undecidability of {\em Halting Problem}
       
  1188   is established. 
       
  1189 *}
       
  1190 
       
  1191 locale uncomputable = 
       
  1192   -- {* The coding function of TM, interestingly, the detailed definition of this 
       
  1193   funciton @{text "code"} does not affect the final result. *}
       
  1194   fixes code :: "instr list \<Rightarrow> nat" 
       
  1195   -- {* 
       
  1196   The TM @{text "H"} is the one which is assummed being able to solve the Halting problem.
       
  1197   *}
       
  1198   and H :: "instr list"
       
  1199   assumes h_wf[intro]: "tm_wf (H, 0)"
       
  1200   -- {*
       
  1201   The following two assumptions specifies that @{text "H"} does solve the Halting problem.
       
  1202   *}
       
  1203   and h_case: 
       
  1204   "\<And> M n. \<lbrakk>(haltP (M, 0) lm)\<rbrakk> \<Longrightarrow> 
       
  1205              \<exists> na nb. (steps (Suc 0, [], <code M # lm>) (H, 0) na = (0, Bk\<up>nb, [Oc]))"
       
  1206   and nh_case: 
       
  1207   "\<And> M n. \<lbrakk>(\<not> haltP (M, 0) lm)\<rbrakk> \<Longrightarrow>
       
  1208              \<exists> na nb. (steps (Suc 0, [],  <code M # lm>) (H, 0) na = (0, Bk\<up>nb, [Oc, Oc]))"
       
  1209 begin
       
  1210 
       
  1211 lemma h_newcase: 
       
  1212   "\<And> M n. haltP (M, 0) lm \<Longrightarrow> 
       
  1213   \<exists> na nb. (steps (Suc 0, Bk\<up>x , <code M # lm>) (H, 0) na = (0, Bk\<up>nb, [Oc]))"
       
  1214 proof -
       
  1215   fix M n
       
  1216   assume "haltP (M, 0) lm"
       
  1217   hence "\<exists> na nb. (steps (Suc 0, [], <code M # lm>) (H, 0) na
       
  1218             = (0, Bk\<up>nb, [Oc]))"
       
  1219     apply(erule_tac h_case)
       
  1220     done
       
  1221   from this obtain na nb where 
       
  1222     cond1:"(steps (Suc 0, [], <code M # lm>) (H, 0) na
       
  1223             = (0, Bk\<up>nb, [Oc]))" by blast
       
  1224   thus "\<exists> na nb. (steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na = (0, Bk\<up>nb, [Oc]))"
       
  1225   proof(rule_tac x = na in exI, case_tac "steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na", simp)
       
  1226     fix a b c
       
  1227     assume cond2: "steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na = (a, b, c)"
       
  1228     have "tinres (Bk\<up>nb) b \<and> [Oc] = c \<and> 0 = a"
       
  1229     proof(rule_tac tinres_steps)
       
  1230       show "tinres [] (Bk\<up>x)"
       
  1231         apply(simp add: tinres_def)
       
  1232         apply(auto)
       
  1233         done
       
  1234     next
       
  1235       show "(steps (Suc 0, [], <code M # lm>) (H, 0) na
       
  1236             = (0, Bk\<up>nb, [Oc]))"
       
  1237         by(simp add: cond1)
       
  1238     next
       
  1239       show "steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na = (a, b, c)"
       
  1240         by(simp add: cond2)
       
  1241     qed
       
  1242     thus "a = 0 \<and> (\<exists>nb. b = (Bk\<up>nb)) \<and> c = [Oc]"
       
  1243       by(auto elim: tinres_ex1)
       
  1244   qed
       
  1245 qed
       
  1246 
       
  1247 lemma nh_newcase: "\<And> M n. \<lbrakk>\<not> (haltP (M, 0) lm)\<rbrakk> \<Longrightarrow> 
       
  1248              \<exists> na nb. (steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na = (0, Bk\<up>nb, [Oc, Oc]))"
       
  1249 proof -
       
  1250   fix M n
       
  1251   assume "\<not> haltP (M, 0) lm"
       
  1252   hence "\<exists> na nb. (steps (Suc 0, [], <code M # lm>) (H, 0) na
       
  1253             = (0, Bk\<up>nb, [Oc, Oc]))"
       
  1254     apply(erule_tac nh_case)
       
  1255     done
       
  1256   from this obtain na nb where 
       
  1257     cond1: "(steps (Suc 0, [], <code M # lm>) (H, 0) na
       
  1258             = (0, Bk\<up>nb, [Oc, Oc]))" by blast
       
  1259   thus "\<exists> na nb. (steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na = (0, Bk\<up>nb, [Oc, Oc]))"
       
  1260   proof(rule_tac x = na in exI, case_tac "steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na", simp)
       
  1261     fix a b c
       
  1262     assume cond2: "steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na = (a, b, c)"
       
  1263     have "tinres (Bk\<up>nb) b \<and> [Oc, Oc] = c \<and> 0 = a"
       
  1264     proof(rule_tac tinres_steps)
       
  1265       show "tinres [] (Bk\<up>x)"
       
  1266         apply(auto simp: tinres_def)
       
  1267         done
       
  1268     next
       
  1269       show "(steps (Suc 0, [], <code M # lm>) (H, 0) na
       
  1270             = (0, Bk\<up>nb, [Oc, Oc]))"
       
  1271         by(simp add: cond1)
       
  1272     next
       
  1273       show "steps (Suc 0, Bk\<up>x, <code M # lm>) (H, 0) na = (a, b, c)"
       
  1274         by(simp add: cond2)
       
  1275     qed
       
  1276     thus "a = 0 \<and> (\<exists>nb. b =  Bk\<up>nb) \<and> c = [Oc, Oc]"
       
  1277       by(auto elim: tinres_ex1)
       
  1278   qed
       
  1279 qed
       
  1280    
       
  1281 (*  
       
  1282 lemma haltP_weaking: 
       
  1283   "haltP (tcontra H) (code (tcontra H)) \<Longrightarrow> 
       
  1284     \<exists>stp. isS0 (steps (Suc 0, [], Oc\<^bsup>code (tcontra H)\<^esup>) 
       
  1285           ((tcopy |+| H) |+| dither) stp)"
       
  1286   apply(simp add: haltP_def, auto)
       
  1287   apply(rule_tac x = n in exI, simp add: isS0_def tcontra_def)
       
  1288   done
       
  1289 *)
       
  1290 
       
  1291 definition tcontra :: "instr list \<Rightarrow> instr list"
       
  1292   where
       
  1293   "tcontra h \<equiv> ((tcopy |+| h) |+| dither)"
       
  1294 
       
  1295 declare replicate_Suc[simp del]
       
  1296 
       
  1297 lemma uh_h: "\<not> haltP (tcontra H, 0) [code (tcontra H)]
       
  1298        \<Longrightarrow> haltP (tcontra H, 0) [code (tcontra H)]"
       
  1299 proof(simp only: tcontra_def)
       
  1300   let ?tcontr = "(tcopy |+| H) |+| dither"
       
  1301   let ?cn = "Suc (code ?tcontr)"
       
  1302   let ?P1 = "\<lambda> (l, r). (l = [] \<and> (r::cell list) = Oc\<up>(?cn))"
       
  1303   let ?Q1 = "\<lambda> (l, r). (l = [Bk] \<and> r = Oc\<up>?cn @ Bk # Oc\<up>?cn)"
       
  1304   let ?P2 = "\<lambda> (l, r). (l = [Bk] \<and> r = Oc\<up>?cn @ Bk # Oc\<up>?cn)"
       
  1305   let ?Q2 = "\<lambda>(l, r). (\<exists>nd. l = Bk \<up> nd) \<and> r = [Oc, Oc]"
       
  1306   let ?P3 = ?Q2
       
  1307   let ?Q3 = ?P3
       
  1308   assume h: "\<not> haltP (?tcontr, 0) [code ?tcontr]"
       
  1309   have "{?P1} (?tcontr, 0) {?Q3}"
       
  1310   proof(rule_tac Hoare_plus_halt, auto)
       
  1311     show "?Q2 \<mapsto> ?P3"
       
  1312       apply(simp add: assert_imp_def)
       
  1313       done
       
  1314   next
       
  1315     show "{?P1} (tcopy|+|H, 0) {?Q2}"
       
  1316     proof(rule_tac Hoare_plus_halt, auto)
       
  1317       show "?Q1 \<mapsto> ?P2"
       
  1318         apply(simp add: assert_imp_def)
       
  1319         done
       
  1320     next
       
  1321       show "{?P1} (tcopy, 0) {?Q1}"
       
  1322       proof -
       
  1323         have g: "{inv_init1 ?cn} (tcopy, 0) {inv_end0 ?cn}"
       
  1324           by(rule_tac tcopy_correct1, simp)
       
  1325         thus "?thesis"
       
  1326         proof(rule_tac Hoare_weak)           
       
  1327           show "{inv_init1 ?cn} (tcopy, 0)
       
  1328             {inv_end0 ?cn} " using g by simp
       
  1329         next
       
  1330           show "?P1 \<mapsto> inv_init1 (?cn)"
       
  1331             apply(simp add: inv_init1.simps assert_imp_def)
       
  1332             done
       
  1333         next
       
  1334           show "inv_end0 ?cn \<mapsto> ?Q1"
       
  1335             apply(simp add: assert_imp_def inv_end0.simps)
       
  1336             done
       
  1337         qed
       
  1338       qed
       
  1339     next
       
  1340       show "{?P2} (H, 0) {?Q2}"
       
  1341         using Hoare_def nh_newcase[of ?tcontr "[code ?tcontr]" 1] h
       
  1342         apply(auto)
       
  1343         apply(rule_tac x = na in exI)
       
  1344         apply(simp add: replicate_Suc)
       
  1345         done
       
  1346     qed
       
  1347   next
       
  1348     show "{?P3}(dither, 0){?Q3}"
       
  1349       using Hoare_def
       
  1350     proof(auto)
       
  1351       fix nd
       
  1352       show "\<exists>n. is_final (steps (Suc 0, Bk \<up> nd, [Oc, Oc]) (dither, 0) n) \<and>
       
  1353         (\<lambda>(l, r). (\<exists>nd. l = Bk \<up> nd) \<and> r = [Oc, Oc])
       
  1354         holds_for steps (Suc 0, Bk \<up> nd, [Oc, Oc]) (dither, 0) n"
       
  1355         using dither_halt_rs[of nd]
       
  1356         apply(auto)
       
  1357         apply(rule_tac x = stp in exI, simp)
       
  1358         done
       
  1359     qed
       
  1360   qed    
       
  1361   thus "False"
       
  1362     using h
       
  1363     apply(auto simp: haltP_def Hoare_def)
       
  1364     apply(erule_tac x = n in allE)
       
  1365     apply(case_tac "steps (Suc 0, [], Oc \<up> ?cn) (?tcontr, 0) n")
       
  1366     apply(simp, auto)
       
  1367     apply(erule_tac x = 2 in allE, erule_tac x = 0 in allE)
       
  1368     apply(simp add: numeral_2_eq_2 replicate_Suc)
       
  1369     done
       
  1370 qed
       
  1371   
       
  1372 
       
  1373 lemma h_uh: "haltP (tcontra H, 0) [code (tcontra H)]
       
  1374        \<Longrightarrow> \<not> haltP (tcontra H, 0) [code (tcontra H)]"
       
  1375 proof(simp only: tcontra_def)
       
  1376   let ?tcontr = "(tcopy |+| H) |+| dither"
       
  1377   let ?cn = "Suc (code ?tcontr)"
       
  1378   let ?P1 = "\<lambda> (l, r). (l = [] \<and> (r::cell list) = Oc\<up>(?cn))"
       
  1379   let ?Q1 = "\<lambda> (l, r). (l = [Bk] \<and> r = Oc\<up>?cn @ Bk # Oc\<up>?cn)"
       
  1380   let ?P2 = "\<lambda> (l, r). (l = [Bk] \<and> r = Oc\<up>?cn @ Bk # Oc\<up>?cn)"
       
  1381   let ?Q2 = "\<lambda>(l, r). (\<exists>nd. l = Bk \<up> nd) \<and> r = [Oc]"
       
  1382   let ?P3 = ?Q2
       
  1383   assume h: "haltP (?tcontr, 0) [code ?tcontr]"
       
  1384   have "{?P1} (?tcontr, 0)"
       
  1385   proof(rule_tac Hoare_plus_unhalt, auto)
       
  1386     show "?Q2 \<mapsto> ?P3"
       
  1387       apply(simp add: assert_imp_def)
       
  1388       done
       
  1389   next
       
  1390     show "{?P1} (tcopy|+|H, 0) {?Q2}"
       
  1391     proof(rule_tac Hoare_plus_halt, auto)
       
  1392       show "?Q1 \<mapsto> ?P2"
       
  1393         apply(simp add: assert_imp_def)
       
  1394         done
       
  1395     next
       
  1396       show "{?P1} (tcopy, 0) {?Q1}"
       
  1397       proof -
       
  1398         have g: "{inv_init1 ?cn} (tcopy, 0) {inv_end0 ?cn}"
       
  1399           by(rule_tac tcopy_correct1, simp)
       
  1400         thus "?thesis"
       
  1401         proof(rule_tac Hoare_weak)           
       
  1402           show "{inv_init1 ?cn} (tcopy, 0)
       
  1403             {inv_end0 ?cn} " using g by simp
       
  1404         next
       
  1405           show "?P1 \<mapsto> inv_init1 (?cn)"
       
  1406             apply(simp add: inv_init1.simps assert_imp_def)
       
  1407             done
       
  1408         next
       
  1409           show "inv_end0 ?cn \<mapsto> ?Q1"
       
  1410             apply(simp add: assert_imp_def inv_end0.simps)
       
  1411             done
       
  1412         qed
       
  1413       qed
       
  1414     next
       
  1415       show "{?P2} (H, 0) {?Q2}"
       
  1416         using Hoare_def h_newcase[of ?tcontr "[code ?tcontr]" 1] h
       
  1417         apply(auto)
       
  1418         apply(rule_tac x = na in exI)
       
  1419         apply(simp add: replicate_Suc)
       
  1420         done
       
  1421     qed
       
  1422   next
       
  1423     show "{?P3}(dither, 0)"
       
  1424       using Hoare_unhalt_def
       
  1425     proof(auto)
       
  1426       fix nd n
       
  1427       assume "is_final (steps (Suc 0, Bk \<up> nd, [Oc]) (dither, 0) n)"
       
  1428       thus "False"
       
  1429         using dither_unhalt_rs[of nd n]
       
  1430         by simp
       
  1431     qed
       
  1432   qed    
       
  1433   thus "\<not> True"
       
  1434     using h
       
  1435     apply(auto simp: haltP_def Hoare_unhalt_def)
       
  1436     apply(erule_tac x = n in allE)
       
  1437     apply(case_tac "steps (Suc 0, [], Oc \<up> ?cn) (?tcontr, 0) n", simp)
       
  1438     done
       
  1439 qed
       
  1440       
       
  1441 text {*
       
  1442   @{text "False"} is finally derived.
       
  1443 *}
       
  1444 
       
  1445 lemma false: "False"
       
  1446 using uh_h h_uh
       
  1447 by auto
       
  1448 end
       
  1449 
       
  1450 end
       
  1451