utm/UF.thy
changeset 370 1ce04eb1c8ad
child 371 48b231495281
equal deleted inserted replaced
369:cbb4ac6c8081 370:1ce04eb1c8ad
       
     1 theory UF
       
     2 imports Main rec_def turing_basic GCD abacus
       
     3 begin
       
     4 
       
     5 text {*
       
     6   This theory file constructs the Universal Function @{text "rec_F"}, which is the UTM defined
       
     7   in terms of recursive functions. This @{text "rec_F"} is essentially an 
       
     8   interpreter of Turing Machines. Once the correctness of @{text "rec_F"} is established,
       
     9   UTM can easil be obtained by compling @{text "rec_F"} into the corresponding Turing Machine.
       
    10 *}
       
    11 
       
    12 
       
    13 section {* The construction of component functions *}
       
    14 
       
    15 text {*
       
    16   This section constructs a set of component functions used to construct @{text "rec_F"}.
       
    17   *}
       
    18 
       
    19 text {*
       
    20   The recursive function used to do arithmatic addition.
       
    21 *}
       
    22 definition rec_add :: "recf"
       
    23   where
       
    24   "rec_add \<equiv>  Pr 1 (id 1 0) (Cn 3 s [id 3 2])"
       
    25 
       
    26 text {*
       
    27   The recursive function used to do arithmatic multiplication.
       
    28 *}
       
    29 definition rec_mult :: "recf"
       
    30   where
       
    31   "rec_mult = Pr 1 z (Cn 3 rec_add [id 3 0, id 3 2])"
       
    32 
       
    33 text {*
       
    34   The recursive function used to do arithmatic precede.
       
    35 *}
       
    36 definition rec_pred :: "recf"
       
    37   where
       
    38   "rec_pred = Cn 1 (Pr 1 z (id 3 1)) [id 1 0, id 1 0]"
       
    39 
       
    40 text {*
       
    41   The recursive function used to do arithmatic subtraction.
       
    42 *}
       
    43 definition rec_minus :: "recf" 
       
    44   where
       
    45   "rec_minus = Pr 1 (id 1 0) (Cn 3 rec_pred [id 3 2])"
       
    46 
       
    47 text {*
       
    48   @{text "constn n"} is the recursive function which computes 
       
    49   nature number @{text "n"}.
       
    50 *}
       
    51 fun constn :: "nat \<Rightarrow> recf"
       
    52   where
       
    53   "constn 0 = z"  |
       
    54   "constn (Suc n) = Cn 1 s [constn n]"
       
    55 
       
    56 
       
    57 text {*
       
    58   Signal function, which returns 1 when the input argument is greater than @{text "0"}.
       
    59 *}
       
    60 definition rec_sg :: "recf"
       
    61   where
       
    62   "rec_sg = Cn 1 rec_minus [constn 1, 
       
    63                   Cn 1 rec_minus [constn 1, id 1 0]]"
       
    64 
       
    65 text {*
       
    66   @{text "rec_less"} compares its two arguments, returns @{text "1"} if
       
    67   the first is less than the second; otherwise returns @{text "0"}.
       
    68   *}
       
    69 definition rec_less :: "recf"
       
    70   where
       
    71   "rec_less = Cn 2 rec_sg [Cn 2 rec_minus [id 2 1, id 2 0]]"
       
    72 
       
    73 text {*
       
    74   @{text "rec_not"} inverse its argument: returns @{text "1"} when the
       
    75   argument is @{text "0"}; returns @{text "0"} otherwise.
       
    76   *}
       
    77 definition rec_not :: "recf"
       
    78   where
       
    79   "rec_not = Cn 1 rec_minus [constn 1, id 1 0]"
       
    80 
       
    81 text {*
       
    82   @{text "rec_eq"} compares its two arguments: returns @{text "1"}
       
    83   if they are equal; return @{text "0"} otherwise.
       
    84   *}
       
    85 definition rec_eq :: "recf"
       
    86   where
       
    87   "rec_eq = Cn 2 rec_minus [Cn 2 (constn 1) [id 2 0], 
       
    88              Cn 2 rec_add [Cn 2 rec_minus [id 2 0, id 2 1], 
       
    89                Cn 2 rec_minus [id 2 1, id 2 0]]]"
       
    90 
       
    91 text {*
       
    92   @{text "rec_conj"} computes the conjunction of its two arguments, 
       
    93   returns @{text "1"} if both of them are non-zero; returns @{text "0"}
       
    94   otherwise.
       
    95   *}
       
    96 definition rec_conj :: "recf"
       
    97   where
       
    98   "rec_conj = Cn 2 rec_sg [Cn 2 rec_mult [id 2 0, id 2 1]] "
       
    99 
       
   100 text {*
       
   101   @{text "rec_disj"} computes the disjunction of its two arguments, 
       
   102   returns @{text "0"} if both of them are zero; returns @{text "0"}
       
   103   otherwise.
       
   104   *}
       
   105 definition rec_disj :: "recf"
       
   106   where
       
   107   "rec_disj = Cn 2 rec_sg [Cn 2 rec_add [id 2 0, id 2 1]]"
       
   108 
       
   109 
       
   110 text {*
       
   111   Computes the arity of recursive function.
       
   112   *}
       
   113 
       
   114 fun arity :: "recf \<Rightarrow> nat"
       
   115   where
       
   116   "arity z = 1" 
       
   117 | "arity s = 1"
       
   118 | "arity (id m n) = m"
       
   119 | "arity (Cn n f gs) = n"
       
   120 | "arity (Pr n f g) = Suc n"
       
   121 | "arity (Mn n f) = n"
       
   122 
       
   123 text {*
       
   124   @{text "get_fstn_args n (Suc k)"} returns
       
   125   @{text "[id n 0, id n 1, id n 2, \<dots>, id n k]"}, 
       
   126   the effect of which is to take out the first @{text "Suc k"} 
       
   127   arguments out of the @{text "n"} input arguments.
       
   128   *}
       
   129 (* get_fstn_args *)
       
   130 fun get_fstn_args :: "nat \<Rightarrow>  nat \<Rightarrow> recf list"
       
   131   where
       
   132   "get_fstn_args n 0 = []"
       
   133 | "get_fstn_args n (Suc y) = get_fstn_args n y @ [id n y]"
       
   134 
       
   135 text {*
       
   136   @{text "rec_sigma f"} returns the recursive functions which 
       
   137   sums up the results of @{text "f"}:
       
   138   \[
       
   139   (rec\_sigma f)(x, y) = f(x, 0) + f(x, 1) + \cdots + f(x, y)
       
   140   \]
       
   141 *}
       
   142 fun rec_sigma :: "recf \<Rightarrow> recf"
       
   143   where
       
   144   "rec_sigma rf = 
       
   145        (let vl = arity rf in 
       
   146           Pr (vl - 1) (Cn (vl - 1) rf (get_fstn_args (vl - 1) (vl - 1) @ 
       
   147                     [Cn (vl - 1) (constn 0) [id (vl - 1) 0]])) 
       
   148              (Cn (Suc vl) rec_add [id (Suc vl) vl, 
       
   149                     Cn (Suc vl) rf (get_fstn_args (Suc vl) (vl - 1) 
       
   150                         @ [Cn (Suc vl) s [id (Suc vl) (vl - 1)]])]))"
       
   151 
       
   152 text {*
       
   153   @{text "rec_exec"} is the interpreter function for
       
   154   reursive functions. The function is defined such that 
       
   155   it always returns meaningful results for primitive recursive 
       
   156   functions.
       
   157   *}
       
   158 function rec_exec :: "recf \<Rightarrow> nat list \<Rightarrow> nat"
       
   159   where
       
   160   "rec_exec z xs = 0" |
       
   161   "rec_exec s xs = (Suc (xs ! 0))" |
       
   162   "rec_exec (id m n) xs = (xs ! n)" |
       
   163   "rec_exec (Cn n f gs) xs = 
       
   164              (let ys = (map (\<lambda> a. rec_exec a xs) gs) in 
       
   165                                   rec_exec f ys)" | 
       
   166   "rec_exec (Pr n f g) xs = 
       
   167      (if last xs = 0 then 
       
   168                   rec_exec f (butlast xs)
       
   169       else rec_exec g (butlast xs @ [last xs - 1] @
       
   170             [rec_exec (Pr n f g) (butlast xs @ [last xs - 1])]))" |
       
   171   "rec_exec (Mn n f) xs = (LEAST x. rec_exec f (xs @ [x]) = 0)"
       
   172 by pat_completeness auto
       
   173 termination
       
   174 proof 
       
   175   show "wf (measures [\<lambda> (r, xs). size r, (\<lambda> (r, xs). last xs)])" 
       
   176     by auto
       
   177 next
       
   178   fix n f gs xs x
       
   179   assume "(x::recf) \<in> set gs" 
       
   180   thus "((x, xs), Cn n f gs, xs) \<in> 
       
   181     measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]"
       
   182     by(induct gs, auto)
       
   183 next
       
   184   fix n f gs xs x
       
   185   assume "x = map (\<lambda>a. rec_exec a xs) gs"
       
   186     "\<And>x. x \<in> set gs \<Longrightarrow> rec_exec_dom (x, xs)" 
       
   187   thus "((f, x), Cn n f gs, xs) \<in> 
       
   188     measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]"
       
   189     by(auto)
       
   190 next
       
   191   fix n f g xs
       
   192   show "((f, butlast xs), Pr n f g, xs) \<in>
       
   193     measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]"
       
   194     by auto
       
   195 next
       
   196   fix n f g xs
       
   197   assume "last xs \<noteq> (0::nat)" thus 
       
   198     "((Pr n f g, butlast xs @ [last xs - 1]), Pr n f g, xs) 
       
   199     \<in> measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]"
       
   200     by auto
       
   201 next
       
   202   fix n f g xs
       
   203   show "((g, butlast xs @ [last xs - 1] @ [rec_exec (Pr n f g) (butlast xs @ [last xs - 1])]), 
       
   204     Pr n f g, xs) \<in> measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]"
       
   205     by auto
       
   206 next
       
   207   fix n f xs x
       
   208   show "((f, xs @ [x]), Mn n f, xs) \<in> 
       
   209     measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]"
       
   210     by auto
       
   211 qed
       
   212 
       
   213 declare rec_exec.simps[simp del] constn.simps[simp del]
       
   214 
       
   215 text {*
       
   216   Correctness of @{text "rec_add"}.
       
   217   *}
       
   218 lemma add_lemma: "\<And> x y. rec_exec rec_add [x, y] =  x + y"
       
   219 by(induct_tac y, auto simp: rec_add_def rec_exec.simps)
       
   220 
       
   221 text {*
       
   222   Correctness of @{text "rec_mult"}.
       
   223   *}
       
   224 lemma mult_lemma: "\<And> x y. rec_exec rec_mult [x, y] = x * y"
       
   225 by(induct_tac y, auto simp: rec_mult_def rec_exec.simps add_lemma)
       
   226 
       
   227 text {*
       
   228   Correctness of @{text "rec_pred"}.
       
   229   *}
       
   230 lemma pred_lemma: "\<And> x. rec_exec rec_pred [x] =  x - 1"
       
   231 by(induct_tac x, auto simp: rec_pred_def rec_exec.simps)
       
   232 
       
   233 text {*
       
   234   Correctness of @{text "rec_minus"}.
       
   235   *}
       
   236 lemma minus_lemma: "\<And> x y. rec_exec rec_minus [x, y] = x - y"
       
   237 by(induct_tac y, auto simp: rec_exec.simps rec_minus_def pred_lemma)
       
   238 
       
   239 text {*
       
   240   Correctness of @{text "rec_sg"}.
       
   241   *}
       
   242 lemma sg_lemma: "\<And> x. rec_exec rec_sg [x] = (if x = 0 then 0 else 1)"
       
   243 by(auto simp: rec_sg_def minus_lemma rec_exec.simps constn.simps)
       
   244 
       
   245 text {*
       
   246   Correctness of @{text "constn"}.
       
   247   *}
       
   248 lemma constn_lemma: "rec_exec (constn n) [x] = n"
       
   249 by(induct n, auto simp: rec_exec.simps constn.simps)
       
   250 
       
   251 text {*
       
   252   Correctness of @{text "rec_less"}.
       
   253   *}
       
   254 lemma less_lemma: "\<And> x y. rec_exec rec_less [x, y] = 
       
   255   (if x < y then 1 else 0)"
       
   256 by(induct_tac y, auto simp: rec_exec.simps 
       
   257   rec_less_def minus_lemma sg_lemma)
       
   258 
       
   259 text {*
       
   260   Correctness of @{text "rec_not"}.
       
   261   *}
       
   262 lemma not_lemma: 
       
   263   "\<And> x. rec_exec rec_not [x] = (if x = 0 then 1 else 0)"
       
   264 by(induct_tac x, auto simp: rec_exec.simps rec_not_def
       
   265   constn_lemma minus_lemma)
       
   266 
       
   267 text {*
       
   268   Correctness of @{text "rec_eq"}.
       
   269   *}
       
   270 lemma eq_lemma: "\<And> x y. rec_exec rec_eq [x, y] = (if x = y then 1 else 0)"
       
   271 by(induct_tac y, auto simp: rec_exec.simps rec_eq_def constn_lemma add_lemma minus_lemma)
       
   272 
       
   273 text {*
       
   274   Correctness of @{text "rec_conj"}.
       
   275   *}
       
   276 lemma conj_lemma: "\<And> x y. rec_exec rec_conj [x, y] = (if x = 0 \<or> y = 0 then 0 
       
   277                                                        else 1)"
       
   278 by(induct_tac y, auto simp: rec_exec.simps sg_lemma rec_conj_def mult_lemma)
       
   279 
       
   280 
       
   281 text {*
       
   282   Correctness of @{text "rec_disj"}.
       
   283   *}
       
   284 lemma disj_lemma: "\<And> x y. rec_exec rec_disj [x, y] = (if x = 0 \<and> y = 0 then 0
       
   285                                                      else 1)"
       
   286 by(induct_tac y, auto simp: rec_disj_def sg_lemma add_lemma rec_exec.simps)
       
   287 
       
   288 
       
   289 text {*
       
   290   @{text "primrec recf n"} is true iff 
       
   291   @{text "recf"} is a primitive recursive function 
       
   292   with arity @{text "n"}.
       
   293   *}
       
   294 inductive primerec :: "recf \<Rightarrow> nat \<Rightarrow> bool"
       
   295   where
       
   296 prime_z[intro]:  "primerec z (Suc 0)" |
       
   297 prime_s[intro]:  "primerec s (Suc 0)" |
       
   298 prime_id[intro!]: "\<lbrakk>n < m\<rbrakk> \<Longrightarrow> primerec (id m n) m" |
       
   299 prime_cn[intro!]: "\<lbrakk>primerec f k; length gs = k; 
       
   300   \<forall> i < length gs. primerec (gs ! i) m; m = n\<rbrakk> 
       
   301   \<Longrightarrow> primerec (Cn n f gs) m" |
       
   302 prime_pr[intro!]: "\<lbrakk>primerec f n; 
       
   303   primerec g (Suc (Suc n)); m = Suc n\<rbrakk> 
       
   304   \<Longrightarrow> primerec (Pr n f g) m" 
       
   305 
       
   306 inductive_cases prime_cn_reverse'[elim]: "primerec (Cn n f gs) n" 
       
   307 inductive_cases prime_mn_reverse: "primerec (Mn n f) m" 
       
   308 inductive_cases prime_z_reverse[elim]: "primerec z n"
       
   309 inductive_cases prime_s_reverse[elim]: "primerec s n"
       
   310 inductive_cases prime_id_reverse[elim]: "primerec (id m n) k"
       
   311 inductive_cases prime_cn_reverse[elim]: "primerec (Cn n f gs) m"
       
   312 inductive_cases prime_pr_reverse[elim]: "primerec (Pr n f g) m"
       
   313 
       
   314 declare mult_lemma[simp] add_lemma[simp] pred_lemma[simp] 
       
   315         minus_lemma[simp] sg_lemma[simp] constn_lemma[simp] 
       
   316         less_lemma[simp] not_lemma[simp] eq_lemma[simp]
       
   317         conj_lemma[simp] disj_lemma[simp]
       
   318 
       
   319 text {*
       
   320   @{text "Sigma"} is the logical specification of 
       
   321   the recursive function @{text "rec_sigma"}.
       
   322   *}
       
   323 function Sigma :: "(nat list \<Rightarrow> nat) \<Rightarrow> nat list \<Rightarrow> nat"
       
   324   where
       
   325   "Sigma g xs = (if last xs = 0 then g xs
       
   326                  else (Sigma g (butlast xs @ [last xs - 1]) +
       
   327                        g xs)) "
       
   328 by pat_completeness auto
       
   329 termination
       
   330 proof
       
   331   show "wf (measure (\<lambda> (f, xs). last xs))" by auto
       
   332 next
       
   333   fix g xs
       
   334   assume "last (xs::nat list) \<noteq> 0"
       
   335   thus "((g, butlast xs @ [last xs - 1]), g, xs)  
       
   336                    \<in> measure (\<lambda>(f, xs). last xs)"
       
   337     by auto
       
   338 qed
       
   339 
       
   340 declare rec_exec.simps[simp del] get_fstn_args.simps[simp del]
       
   341         arity.simps[simp del] Sigma.simps[simp del]
       
   342         rec_sigma.simps[simp del]
       
   343 
       
   344 
       
   345 section {* Properties of @{text rec_sigma} *}
       
   346 
       
   347 lemma [simp]: "arity z = 1"
       
   348  by(simp add: arity.simps)
       
   349 
       
   350 lemma rec_pr_0_simp_rewrite: "
       
   351   rec_exec (Pr n f g) (xs @ [0]) = rec_exec f xs"
       
   352 by(simp add: rec_exec.simps)
       
   353 
       
   354 lemma rec_pr_0_simp_rewrite_single_param: "
       
   355   rec_exec (Pr n f g) [0] = rec_exec f []"
       
   356 by(simp add: rec_exec.simps)
       
   357 
       
   358 lemma rec_pr_Suc_simp_rewrite: 
       
   359   "rec_exec (Pr n f g) (xs @ [Suc x]) =
       
   360                        rec_exec g (xs @ [x] @ 
       
   361                         [rec_exec (Pr n f g) (xs @ [x])])"
       
   362 by(simp add: rec_exec.simps)
       
   363 
       
   364 lemma rec_pr_Suc_simp_rewrite_single_param: 
       
   365   "rec_exec (Pr n f g) ([Suc x]) =
       
   366            rec_exec g ([x] @ [rec_exec (Pr n f g) ([x])])"
       
   367 by(simp add: rec_exec.simps)
       
   368 
       
   369 thm Sigma.simps
       
   370 
       
   371 lemma Sigma_0_simp_rewrite_single_param:
       
   372   "Sigma f [0] = f [0]"
       
   373 by(simp add: Sigma.simps)
       
   374 
       
   375 lemma Sigma_0_simp_rewrite:
       
   376   "Sigma f (xs @ [0]) = f (xs @ [0])"
       
   377 by(simp add: Sigma.simps)
       
   378 
       
   379 lemma Sigma_Suc_simp_rewrite: 
       
   380   "Sigma f (xs @ [Suc x]) = Sigma f (xs @ [x]) + f (xs @ [Suc x])"
       
   381 by(simp add: Sigma.simps)
       
   382 
       
   383 lemma Sigma_Suc_simp_rewrite_single: 
       
   384   "Sigma f ([Suc x]) = Sigma f ([x]) + f ([Suc x])"
       
   385 by(simp add: Sigma.simps)
       
   386 
       
   387 lemma  [simp]: "(xs @ ys) ! (Suc (length xs)) = ys ! 1"
       
   388 by(simp add: nth_append)
       
   389   
       
   390 lemma get_fstn_args_take: "\<lbrakk>length xs = m; n \<le> m\<rbrakk> \<Longrightarrow> 
       
   391   map (\<lambda> f. rec_exec f xs) (get_fstn_args m n)= take n xs"
       
   392 proof(induct n)
       
   393   case 0 thus "?case"
       
   394     by(simp add: get_fstn_args.simps)
       
   395 next
       
   396   case (Suc n) thus "?case"
       
   397     by(simp add: get_fstn_args.simps rec_exec.simps 
       
   398              take_Suc_conv_app_nth)
       
   399 qed
       
   400     
       
   401 lemma [simp]: "primerec f n \<Longrightarrow> arity f = n"
       
   402   apply(case_tac f)
       
   403   apply(auto simp: arity.simps )
       
   404   apply(erule_tac prime_mn_reverse)
       
   405   done
       
   406 
       
   407 lemma rec_sigma_Suc_simp_rewrite: 
       
   408   "primerec f (Suc (length xs))
       
   409     \<Longrightarrow> rec_exec (rec_sigma f) (xs @ [Suc x]) = 
       
   410     rec_exec (rec_sigma f) (xs @ [x]) + rec_exec f (xs @ [Suc x])"
       
   411   apply(induct x)
       
   412   apply(auto simp: rec_sigma.simps Let_def rec_pr_Suc_simp_rewrite
       
   413                    rec_exec.simps get_fstn_args_take)
       
   414   done      
       
   415 
       
   416 text {*
       
   417   The correctness of @{text "rec_sigma"} with respect to its specification.
       
   418   *}
       
   419 lemma sigma_lemma: 
       
   420   "primerec rg (Suc (length xs))
       
   421      \<Longrightarrow> rec_exec (rec_sigma rg) (xs @ [x]) = Sigma (rec_exec rg) (xs @ [x])"
       
   422 apply(induct x)
       
   423 apply(auto simp: rec_exec.simps rec_sigma.simps Let_def 
       
   424          get_fstn_args_take Sigma_0_simp_rewrite
       
   425          Sigma_Suc_simp_rewrite) 
       
   426 done
       
   427 
       
   428 text {*
       
   429   @{text "rec_accum f (x1, x2, \<dots>, xn, k) = 
       
   430            f(x1, x2, \<dots>, xn, 0) * 
       
   431            f(x1, x2, \<dots>, xn, 1) *
       
   432                \<dots> 
       
   433            f(x1, x2, \<dots>, xn, k)"}
       
   434 *}
       
   435 fun rec_accum :: "recf \<Rightarrow> recf"
       
   436   where
       
   437   "rec_accum rf = 
       
   438        (let vl = arity rf in 
       
   439           Pr (vl - 1) (Cn (vl - 1) rf (get_fstn_args (vl - 1) (vl - 1) @ 
       
   440                      [Cn (vl - 1) (constn 0) [id (vl - 1) 0]])) 
       
   441              (Cn (Suc vl) rec_mult [id (Suc vl) (vl), 
       
   442                     Cn (Suc vl) rf (get_fstn_args (Suc vl) (vl - 1) 
       
   443                       @ [Cn (Suc vl) s [id (Suc vl) (vl - 1)]])]))"
       
   444 
       
   445 text {*
       
   446   @{text "Accum"} is the formal specification of @{text "rec_accum"}.
       
   447   *}
       
   448 function Accum :: "(nat list \<Rightarrow> nat) \<Rightarrow> nat list \<Rightarrow> nat"
       
   449   where
       
   450   "Accum f xs = (if last xs = 0 then f xs 
       
   451                      else (Accum f (butlast xs @ [last xs - 1]) *
       
   452                        f xs))"
       
   453 by pat_completeness auto
       
   454 termination
       
   455 proof
       
   456   show "wf (measure (\<lambda> (f, xs). last xs))"
       
   457     by auto
       
   458 next
       
   459   fix f xs
       
   460   assume "last xs \<noteq> (0::nat)"
       
   461   thus "((f, butlast xs @ [last xs - 1]), f, xs) \<in> 
       
   462             measure (\<lambda>(f, xs). last xs)"
       
   463     by auto
       
   464 qed
       
   465 
       
   466 lemma rec_accum_Suc_simp_rewrite: 
       
   467   "primerec f (Suc (length xs))
       
   468     \<Longrightarrow> rec_exec (rec_accum f) (xs @ [Suc x]) = 
       
   469     rec_exec (rec_accum f) (xs @ [x]) * rec_exec f (xs @ [Suc x])"
       
   470   apply(induct x)
       
   471   apply(auto simp: rec_sigma.simps Let_def rec_pr_Suc_simp_rewrite
       
   472                    rec_exec.simps get_fstn_args_take)
       
   473   done  
       
   474 
       
   475 text {*
       
   476   The correctness of @{text "rec_accum"} with respect to its specification.
       
   477 *}
       
   478 lemma accum_lemma :
       
   479   "primerec rg (Suc (length xs))
       
   480      \<Longrightarrow> rec_exec (rec_accum rg) (xs @ [x]) = Accum (rec_exec rg) (xs @ [x])"
       
   481 apply(induct x)
       
   482 apply(auto simp: rec_exec.simps rec_sigma.simps Let_def 
       
   483                      get_fstn_args_take)
       
   484 done
       
   485 
       
   486 declare rec_accum.simps [simp del]
       
   487 
       
   488 text {*
       
   489   @{text "rec_all t f (x1, x2, \<dots>, xn)"} 
       
   490   computes the charactrization function of the following FOL formula:
       
   491   @{text "(\<forall> x \<le> t(x1, x2, \<dots>, xn). (f(x1, x2, \<dots>, xn, x) > 0))"}
       
   492 *}
       
   493 fun rec_all :: "recf \<Rightarrow> recf \<Rightarrow> recf"
       
   494   where
       
   495   "rec_all rt rf = 
       
   496     (let vl = arity rf in
       
   497        Cn (vl - 1) rec_sg [Cn (vl - 1) (rec_accum rf) 
       
   498                  (get_fstn_args (vl - 1) (vl - 1) @ [rt])])"
       
   499 
       
   500 lemma rec_accum_ex: "primerec rf (Suc (length xs)) \<Longrightarrow>
       
   501      (rec_exec (rec_accum rf) (xs @ [x]) = 0) = 
       
   502       (\<exists> t \<le> x. rec_exec rf (xs @ [t]) = 0)"
       
   503 apply(induct x, simp_all add: rec_accum_Suc_simp_rewrite)
       
   504 apply(simp add: rec_exec.simps rec_accum.simps get_fstn_args_take, 
       
   505       auto)
       
   506 apply(rule_tac x = ta in exI, simp)
       
   507 apply(case_tac "t = Suc x", simp_all)
       
   508 apply(rule_tac x = t in exI, simp)
       
   509 done
       
   510 
       
   511 text {*
       
   512   The correctness of @{text "rec_all"}.
       
   513   *}
       
   514 lemma all_lemma: 
       
   515   "\<lbrakk>primerec rf (Suc (length xs));
       
   516     primerec rt (length xs)\<rbrakk>
       
   517   \<Longrightarrow> rec_exec (rec_all rt rf) xs = (if (\<forall> x \<le> (rec_exec rt xs). 0 < rec_exec rf (xs @ [x])) then 1
       
   518                                                                                               else 0)"
       
   519 apply(auto simp: rec_all.simps)
       
   520 apply(simp add: rec_exec.simps map_append get_fstn_args_take split: if_splits)
       
   521 apply(drule_tac x = "rec_exec rt xs" in rec_accum_ex)
       
   522 apply(case_tac "rec_exec (rec_accum rf) (xs @ [rec_exec rt xs]) = 0", simp_all)
       
   523 apply(erule_tac exE, erule_tac x = t in allE, simp)
       
   524 apply(simp add: rec_exec.simps map_append get_fstn_args_take)
       
   525 apply(drule_tac x = "rec_exec rt xs" in rec_accum_ex)
       
   526 apply(case_tac "rec_exec (rec_accum rf) (xs @ [rec_exec rt xs]) = 0", simp, simp)
       
   527 apply(erule_tac x = x in allE, simp)
       
   528 done
       
   529 
       
   530 text {*
       
   531   @{text "rec_ex t f (x1, x2, \<dots>, xn)"} 
       
   532   computes the charactrization function of the following FOL formula:
       
   533   @{text "(\<exists> x \<le> t(x1, x2, \<dots>, xn). (f(x1, x2, \<dots>, xn, x) > 0))"}
       
   534 *}
       
   535 fun rec_ex :: "recf \<Rightarrow> recf \<Rightarrow> recf"
       
   536   where
       
   537   "rec_ex rt rf = 
       
   538        (let vl = arity rf in 
       
   539          Cn (vl - 1) rec_sg [Cn (vl - 1) (rec_sigma rf) 
       
   540                   (get_fstn_args (vl - 1) (vl - 1) @ [rt])])"
       
   541 
       
   542 lemma rec_sigma_ex: "primerec rf (Suc (length xs))
       
   543           \<Longrightarrow> (rec_exec (rec_sigma rf) (xs @ [x]) = 0) = 
       
   544                           (\<forall> t \<le> x. rec_exec rf (xs @ [t]) = 0)"
       
   545 apply(induct x, simp_all add: rec_sigma_Suc_simp_rewrite)
       
   546 apply(simp add: rec_exec.simps rec_sigma.simps 
       
   547                 get_fstn_args_take, auto)
       
   548 apply(case_tac "t = Suc x", simp_all)
       
   549 done
       
   550 
       
   551 text {*
       
   552   The correctness of @{text "ex_lemma"}.
       
   553   *}
       
   554 lemma ex_lemma:"
       
   555   \<lbrakk>primerec rf (Suc (length xs));
       
   556    primerec rt (length xs)\<rbrakk>
       
   557 \<Longrightarrow> (rec_exec (rec_ex rt rf) xs =
       
   558     (if (\<exists> x \<le> (rec_exec rt xs). 0 <rec_exec rf (xs @ [x])) then 1
       
   559      else 0))"
       
   560 apply(auto simp: rec_ex.simps rec_exec.simps map_append get_fstn_args_take 
       
   561             split: if_splits)
       
   562 apply(drule_tac x = "rec_exec rt xs" in rec_sigma_ex, simp)
       
   563 apply(drule_tac x = "rec_exec rt xs" in rec_sigma_ex, simp)
       
   564 done
       
   565 
       
   566 text {*
       
   567   Defintiion of @{text "Min[R]"} on page 77 of Boolos's book.
       
   568 *}
       
   569 
       
   570 fun Minr :: "(nat list \<Rightarrow> bool) \<Rightarrow> nat list \<Rightarrow> nat \<Rightarrow> nat"
       
   571   where "Minr Rr xs w = (let setx = {y | y. (y \<le> w) \<and> Rr (xs @ [y])} in 
       
   572                         if (setx = {}) then (Suc w)
       
   573                                        else (Min setx))"
       
   574 
       
   575 declare Minr.simps[simp del] rec_all.simps[simp del]
       
   576 
       
   577 text {*
       
   578   The following is a set of auxilliary lemmas about @{text "Minr"}.
       
   579 *}
       
   580 lemma Minr_range: "Minr Rr xs w \<le> w \<or> Minr Rr xs w = Suc w"
       
   581 apply(auto simp: Minr.simps)
       
   582 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<le> x")
       
   583 apply(erule_tac order_trans, simp)
       
   584 apply(rule_tac Min_le, auto)
       
   585 done
       
   586 
       
   587 lemma [simp]: "{x. x \<le> Suc w \<and> Rr (xs @ [x])}
       
   588     = (if Rr (xs @ [Suc w]) then insert (Suc w) 
       
   589                               {x. x \<le> w \<and> Rr (xs @ [x])}
       
   590       else {x. x \<le> w \<and> Rr (xs @ [x])})"
       
   591 by(auto, case_tac "x = Suc w", auto)
       
   592 
       
   593 lemma [simp]: "Minr Rr xs w \<le> w \<Longrightarrow> Minr Rr xs (Suc w) = Minr Rr xs w"
       
   594 apply(simp add: Minr.simps, auto)
       
   595 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
       
   596 done
       
   597 
       
   598 lemma [simp]: "\<forall>x\<le>w. \<not> Rr (xs @ [x]) \<Longrightarrow>  
       
   599                            {x. x \<le> w \<and> Rr (xs @ [x])} = {} "
       
   600 by auto
       
   601 
       
   602 lemma [simp]: "\<lbrakk>Minr Rr xs w = Suc w; Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> 
       
   603                                        Minr Rr xs (Suc w) = Suc w"
       
   604 apply(simp add: Minr.simps)
       
   605 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
       
   606 done
       
   607  
       
   608 lemma [simp]: "\<lbrakk>Minr Rr xs w = Suc w; \<not> Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> 
       
   609                                    Minr Rr xs (Suc w) = Suc (Suc w)"
       
   610 apply(simp add: Minr.simps)
       
   611 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
       
   612 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<in> 
       
   613                                 {x. x \<le> w \<and> Rr (xs @ [x])}", simp)
       
   614 apply(rule_tac Min_in, auto)
       
   615 done
       
   616 
       
   617 lemma Minr_Suc_simp: 
       
   618    "Minr Rr xs (Suc w) = 
       
   619       (if Minr Rr xs w \<le> w then Minr Rr xs w
       
   620        else if (Rr (xs @ [Suc w])) then (Suc w)
       
   621        else Suc (Suc w))"
       
   622 by(insert Minr_range[of Rr xs w], auto)
       
   623 
       
   624 text {* 
       
   625   @{text "rec_Minr"} is the recursive function 
       
   626   used to implement @{text "Minr"}:
       
   627   if @{text "Rr"} is implemented by a recursive function @{text "recf"},
       
   628   then @{text "rec_Minr recf"} is the recursive function used to 
       
   629   implement @{text "Minr Rr"}
       
   630  *}
       
   631 fun rec_Minr :: "recf \<Rightarrow> recf"
       
   632   where
       
   633   "rec_Minr rf = 
       
   634      (let vl = arity rf
       
   635       in let rq = rec_all (id vl (vl - 1)) (Cn (Suc vl) 
       
   636               rec_not [Cn (Suc vl) rf 
       
   637                     (get_fstn_args (Suc vl) (vl - 1) @
       
   638                                         [id (Suc vl) (vl)])]) 
       
   639       in  rec_sigma rq)"
       
   640 
       
   641 lemma length_getpren_params[simp]: "length (get_fstn_args m n) = n"
       
   642 by(induct n, auto simp: get_fstn_args.simps)
       
   643 
       
   644 lemma length_app:
       
   645   "(length (get_fstn_args (arity rf - Suc 0)
       
   646                            (arity rf - Suc 0)
       
   647    @ [Cn (arity rf - Suc 0) (constn 0)
       
   648            [recf.id (arity rf - Suc 0) 0]]))
       
   649     = (Suc (arity rf - Suc 0))"
       
   650   apply(simp)
       
   651 done
       
   652 
       
   653 lemma primerec_accum: "primerec (rec_accum rf) n \<Longrightarrow> primerec rf n"
       
   654 apply(auto simp: rec_accum.simps Let_def)
       
   655 apply(erule_tac prime_pr_reverse, simp)
       
   656 apply(erule_tac prime_cn_reverse, simp only: length_app)
       
   657 done
       
   658 
       
   659 lemma primerec_all: "primerec (rec_all rt rf) n \<Longrightarrow>
       
   660                        primerec rt n \<and> primerec rf (Suc n)"
       
   661 apply(simp add: rec_all.simps Let_def)
       
   662 apply(erule_tac prime_cn_reverse, simp)
       
   663 apply(erule_tac prime_cn_reverse, simp)
       
   664 apply(erule_tac x = n in allE, simp add: nth_append primerec_accum)
       
   665 done
       
   666 
       
   667 lemma min_Suc_Suc[simp]: "min (Suc (Suc x)) x = x"
       
   668  by auto
       
   669 
       
   670 declare numeral_3_eq_3[simp]
       
   671 
       
   672 lemma [intro]: "primerec rec_pred (Suc 0)"
       
   673 apply(simp add: rec_pred_def)
       
   674 apply(rule_tac prime_cn, auto)
       
   675 apply(case_tac i, auto intro: prime_id)
       
   676 done
       
   677 
       
   678 lemma [intro]: "primerec rec_minus (Suc (Suc 0))"
       
   679   apply(auto simp: rec_minus_def)
       
   680   done
       
   681 
       
   682 lemma [intro]: "primerec (constn n) (Suc 0)"
       
   683   apply(induct n)
       
   684   apply(auto simp: constn.simps intro: prime_z prime_cn prime_s)
       
   685   done
       
   686 
       
   687 lemma [intro]: "primerec rec_sg (Suc 0)" 
       
   688   apply(simp add: rec_sg_def)
       
   689   apply(rule_tac k = "Suc (Suc 0)" in prime_cn, auto)
       
   690   apply(case_tac i, auto)
       
   691   apply(case_tac ia, auto intro: prime_id)
       
   692   done
       
   693 
       
   694 lemma [simp]: "length (get_fstn_args m n) = n"
       
   695   apply(induct n)
       
   696   apply(auto simp: get_fstn_args.simps)
       
   697   done
       
   698 
       
   699 lemma  primerec_getpren[elim]: "\<lbrakk>i < n; n \<le> m\<rbrakk> \<Longrightarrow> primerec (get_fstn_args m n ! i) m"
       
   700 apply(induct n, auto simp: get_fstn_args.simps)
       
   701 apply(case_tac "i = n", auto simp: nth_append intro: prime_id)
       
   702 done
       
   703 
       
   704 lemma [intro]: "primerec rec_add (Suc (Suc 0))"
       
   705 apply(simp add: rec_add_def)
       
   706 apply(rule_tac prime_pr, auto)
       
   707 done
       
   708 
       
   709 lemma [intro]:"primerec rec_mult (Suc (Suc 0))"
       
   710 apply(simp add: rec_mult_def )
       
   711 apply(rule_tac prime_pr, auto intro: prime_z)
       
   712 apply(case_tac i, auto intro: prime_id)
       
   713 done  
       
   714 
       
   715 lemma [elim]: "\<lbrakk>primerec rf n; n \<ge> Suc (Suc 0)\<rbrakk>   \<Longrightarrow> 
       
   716                         primerec (rec_accum rf) n"
       
   717 apply(auto simp: rec_accum.simps)
       
   718 apply(simp add: nth_append, auto)
       
   719 apply(case_tac i, auto intro: prime_id)
       
   720 apply(auto simp: nth_append)
       
   721 done
       
   722 
       
   723 lemma primerec_all_iff: 
       
   724   "\<lbrakk>primerec rt n; primerec rf (Suc n); n > 0\<rbrakk> \<Longrightarrow> 
       
   725                                  primerec (rec_all rt rf) n"
       
   726   apply(simp add: rec_all.simps, auto)
       
   727   apply(auto, simp add: nth_append, auto)
       
   728   done
       
   729 
       
   730 lemma [simp]: "Rr (xs @ [0]) \<Longrightarrow> 
       
   731                    Min {x. x = (0::nat) \<and> Rr (xs @ [x])} = 0"
       
   732 by(rule_tac Min_eqI, simp, simp, simp)
       
   733 
       
   734 lemma [intro]: "primerec rec_not (Suc 0)"
       
   735 apply(simp add: rec_not_def)
       
   736 apply(rule prime_cn, auto)
       
   737 apply(case_tac i, auto intro: prime_id)
       
   738 done
       
   739 
       
   740 lemma Min_false1[simp]: "\<lbrakk>\<not> Min {uu. uu \<le> w \<and> 0 < rec_exec rf (xs @ [uu])} \<le> w;
       
   741        x \<le> w; 0 < rec_exec rf (xs @ [x])\<rbrakk>
       
   742       \<Longrightarrow>  False"
       
   743 apply(subgoal_tac "finite {uu. uu \<le> w \<and> 0 < rec_exec rf (xs @ [uu])}")
       
   744 apply(subgoal_tac "{uu. uu \<le> w \<and> 0 < rec_exec rf (xs @ [uu])} \<noteq> {}")
       
   745 apply(simp add: Min_le_iff, simp)
       
   746 apply(rule_tac x = x in exI, simp)
       
   747 apply(simp)
       
   748 done
       
   749 
       
   750 lemma sigma_minr_lemma: 
       
   751   assumes prrf:  "primerec rf (Suc (length xs))"
       
   752   shows "UF.Sigma (rec_exec (rec_all (recf.id (Suc (length xs)) (length xs))
       
   753      (Cn (Suc (Suc (length xs))) rec_not
       
   754       [Cn (Suc (Suc (length xs))) rf (get_fstn_args (Suc (Suc (length xs))) 
       
   755        (length xs) @ [recf.id (Suc (Suc (length xs))) (Suc (length xs))])])))
       
   756       (xs @ [w]) =
       
   757        Minr (\<lambda>args. 0 < rec_exec rf args) xs w"
       
   758 proof(induct w)
       
   759   let ?rt = "(recf.id (Suc (length xs)) ((length xs)))"
       
   760   let ?rf = "(Cn (Suc (Suc (length xs))) 
       
   761     rec_not [Cn (Suc (Suc (length xs))) rf 
       
   762     (get_fstn_args (Suc (Suc (length xs))) (length xs) @ 
       
   763                 [recf.id (Suc (Suc (length xs))) 
       
   764     (Suc ((length xs)))])])"
       
   765   let ?rq = "(rec_all ?rt ?rf)"
       
   766   have prrf: "primerec ?rf (Suc (length (xs @ [0]))) \<and>
       
   767         primerec ?rt (length (xs @ [0]))"
       
   768     apply(auto simp: prrf nth_append)+
       
   769     done
       
   770   show "Sigma (rec_exec (rec_all ?rt ?rf)) (xs @ [0])
       
   771        = Minr (\<lambda>args. 0 < rec_exec rf args) xs 0"
       
   772     apply(simp add: Sigma.simps)
       
   773     apply(simp only: prrf all_lemma,  
       
   774           auto simp: rec_exec.simps get_fstn_args_take Minr.simps)
       
   775     apply(rule_tac Min_eqI, auto)
       
   776     done
       
   777 next
       
   778   fix w
       
   779   let ?rt = "(recf.id (Suc (length xs)) ((length xs)))"
       
   780   let ?rf = "(Cn (Suc (Suc (length xs))) 
       
   781     rec_not [Cn (Suc (Suc (length xs))) rf 
       
   782     (get_fstn_args (Suc (Suc (length xs))) (length xs) @ 
       
   783                 [recf.id (Suc (Suc (length xs))) 
       
   784     (Suc ((length xs)))])])"
       
   785   let ?rq = "(rec_all ?rt ?rf)"
       
   786   assume ind:
       
   787     "Sigma (rec_exec (rec_all ?rt ?rf)) (xs @ [w]) = Minr (\<lambda>args. 0 < rec_exec rf args) xs w"
       
   788   have prrf: "primerec ?rf (Suc (length (xs @ [Suc w]))) \<and>
       
   789         primerec ?rt (length (xs @ [Suc w]))"
       
   790     apply(auto simp: prrf nth_append)+
       
   791     done
       
   792   show "UF.Sigma (rec_exec (rec_all ?rt ?rf))
       
   793          (xs @ [Suc w]) =
       
   794         Minr (\<lambda>args. 0 < rec_exec rf args) xs (Suc w)"
       
   795     apply(auto simp: Sigma_Suc_simp_rewrite ind Minr_Suc_simp)
       
   796     apply(simp_all only: prrf all_lemma)
       
   797     apply(auto simp: rec_exec.simps get_fstn_args_take Let_def Minr.simps split: if_splits)
       
   798     apply(drule_tac Min_false1, simp, simp, simp)
       
   799     apply(case_tac "x = Suc w", simp, simp)
       
   800     apply(drule_tac Min_false1, simp, simp, simp)
       
   801     apply(drule_tac Min_false1, simp, simp, simp)
       
   802     done
       
   803 qed
       
   804 
       
   805 text {*
       
   806   The correctness of @{text "rec_Minr"}.
       
   807   *}
       
   808 lemma Minr_lemma: "
       
   809   \<lbrakk>primerec rf (Suc (length xs))\<rbrakk> 
       
   810      \<Longrightarrow> rec_exec (rec_Minr rf) (xs @ [w]) = 
       
   811             Minr (\<lambda> args. (0 < rec_exec rf args)) xs w"
       
   812 proof -
       
   813   let ?rt = "(recf.id (Suc (length xs)) ((length xs)))"
       
   814   let ?rf = "(Cn (Suc (Suc (length xs))) 
       
   815     rec_not [Cn (Suc (Suc (length xs))) rf 
       
   816     (get_fstn_args (Suc (Suc (length xs))) (length xs) @ 
       
   817                 [recf.id (Suc (Suc (length xs))) 
       
   818     (Suc ((length xs)))])])"
       
   819   let ?rq = "(rec_all ?rt ?rf)"
       
   820   assume h: "primerec rf (Suc (length xs))"
       
   821   have h1: "primerec ?rq (Suc (length xs))"
       
   822     apply(rule_tac primerec_all_iff)
       
   823     apply(auto simp: h nth_append)+
       
   824     done
       
   825   moreover have "arity rf = Suc (length xs)"
       
   826     using h by auto
       
   827   ultimately show "rec_exec (rec_Minr rf) (xs @ [w]) = 
       
   828     Minr (\<lambda> args. (0 < rec_exec rf args)) xs w"
       
   829     apply(simp add: rec_exec.simps rec_Minr.simps arity.simps Let_def 
       
   830                     sigma_lemma all_lemma)
       
   831     apply(rule_tac  sigma_minr_lemma)
       
   832     apply(simp add: h)
       
   833     done
       
   834 qed
       
   835     
       
   836 text {* 
       
   837   @{text "rec_le"} is the comparasion function 
       
   838   which compares its two arguments, testing whether the 
       
   839   first is less or equal to the second.
       
   840   *}
       
   841 definition rec_le :: "recf"
       
   842   where
       
   843   "rec_le = Cn (Suc (Suc 0)) rec_disj [rec_less, rec_eq]"
       
   844 
       
   845 text {*
       
   846   The correctness of @{text "rec_le"}.
       
   847   *}
       
   848 lemma le_lemma: 
       
   849   "\<And>x y. rec_exec rec_le [x, y] = (if (x \<le> y) then 1 else 0)"
       
   850 by(auto simp: rec_le_def rec_exec.simps)
       
   851 
       
   852 text {*
       
   853   Defintiion of @{text "Max[Rr]"} on page 77 of Boolos's book.
       
   854 *}
       
   855 
       
   856 fun Maxr :: "(nat list \<Rightarrow> bool) \<Rightarrow> nat list \<Rightarrow> nat \<Rightarrow> nat"
       
   857   where
       
   858   "Maxr Rr xs w = (let setx = {y. y \<le> w \<and> Rr (xs @[y])} in 
       
   859                   if setx = {} then 0
       
   860                   else Max setx)"
       
   861 
       
   862 text {*
       
   863   @{text "rec_maxr"} is the recursive function 
       
   864   used to implementation @{text "Maxr"}.
       
   865   *}
       
   866 fun rec_maxr :: "recf \<Rightarrow> recf"
       
   867   where
       
   868   "rec_maxr rr = (let vl = arity rr in 
       
   869                   let rt = id (Suc vl) (vl - 1) in
       
   870                   let rf1 = Cn (Suc (Suc vl)) rec_le 
       
   871                     [id (Suc (Suc vl)) 
       
   872                      ((Suc vl)), id (Suc (Suc vl)) (vl)] in
       
   873                   let rf2 = Cn (Suc (Suc vl)) rec_not 
       
   874                       [Cn (Suc (Suc vl)) 
       
   875                            rr (get_fstn_args (Suc (Suc vl)) 
       
   876                             (vl - 1) @ 
       
   877                              [id (Suc (Suc vl)) ((Suc vl))])] in
       
   878                   let rf = Cn (Suc (Suc vl)) rec_disj [rf1, rf2] in
       
   879                   let rq = rec_all rt rf  in
       
   880                   let Qf = Cn (Suc vl) rec_not [rec_all rt rf]
       
   881                   in Cn vl (rec_sigma Qf) (get_fstn_args vl vl @
       
   882                                                          [id vl (vl - 1)]))"
       
   883 
       
   884 declare rec_maxr.simps[simp del] Maxr.simps[simp del] 
       
   885 declare le_lemma[simp]
       
   886 lemma [simp]: "(min (Suc (Suc (Suc (x)))) (x)) = x"
       
   887 by simp
       
   888 
       
   889 declare numeral_2_eq_2[simp]
       
   890 
       
   891 lemma [intro]: "primerec rec_disj (Suc (Suc 0))"
       
   892   apply(simp add: rec_disj_def, auto)
       
   893   apply(auto)
       
   894   apply(case_tac ia, auto intro: prime_id)
       
   895   done
       
   896 
       
   897 lemma [intro]: "primerec rec_less (Suc (Suc 0))"
       
   898   apply(simp add: rec_less_def, auto)
       
   899   apply(auto)
       
   900   apply(case_tac ia , auto intro: prime_id)
       
   901   done
       
   902 
       
   903 lemma [intro]: "primerec rec_eq (Suc (Suc 0))"
       
   904   apply(simp add: rec_eq_def)
       
   905   apply(rule_tac prime_cn, auto)
       
   906   apply(case_tac i, auto)
       
   907   apply(case_tac ia, auto)
       
   908   apply(case_tac [!] i, auto intro: prime_id)
       
   909   done
       
   910 
       
   911 lemma [intro]: "primerec rec_le (Suc (Suc 0))"
       
   912   apply(simp add: rec_le_def)
       
   913   apply(rule_tac prime_cn, auto)
       
   914   apply(case_tac i, auto)
       
   915   done
       
   916 
       
   917 lemma [simp]:  
       
   918   "length ys = Suc n \<Longrightarrow> (take n ys @ [ys ! n, ys ! n]) =  
       
   919                                                   ys @ [ys ! n]"
       
   920 apply(simp)
       
   921 apply(subgoal_tac "\<exists> xs y. ys = xs @ [y]", auto)
       
   922 apply(rule_tac x = "butlast ys" in exI, rule_tac x = "last ys" in exI)
       
   923 apply(case_tac "ys = []", simp_all)
       
   924 done
       
   925 
       
   926 lemma Maxr_Suc_simp: 
       
   927   "Maxr Rr xs (Suc w) =(if Rr (xs @ [Suc w]) then Suc w
       
   928      else Maxr Rr xs w)"
       
   929 apply(auto simp: Maxr.simps)
       
   930 apply(rule_tac max_absorb1)
       
   931 apply(subgoal_tac "(Max {y. y \<le> w \<and> Rr (xs @ [y])} \<le> (Suc w)) =
       
   932   (\<forall>a\<in>{y. y \<le> w \<and> Rr (xs @ [y])}. a \<le> (Suc w))", simp)
       
   933 apply(rule_tac Max_le_iff, auto)
       
   934 done
       
   935 
       
   936 
       
   937 lemma [simp]: "min (Suc n) n = n" by simp
       
   938 
       
   939 lemma Sigma_0: "\<forall> i \<le> n. (f (xs @ [i]) = 0) \<Longrightarrow> 
       
   940                               Sigma f (xs @ [n]) = 0"
       
   941 apply(induct n, simp add: Sigma.simps)
       
   942 apply(simp add: Sigma_Suc_simp_rewrite)
       
   943 done
       
   944   
       
   945 lemma [elim]: "\<forall>k<Suc w. f (xs @ [k]) = Suc 0
       
   946         \<Longrightarrow> Sigma f (xs @ [w]) = Suc w"
       
   947 apply(induct w)
       
   948 apply(simp add: Sigma.simps, simp)
       
   949 apply(simp add: Sigma.simps)
       
   950 done
       
   951 
       
   952 lemma Sigma_max_point: "\<lbrakk>\<forall> k < ma. f (xs @ [k]) = 1;
       
   953         \<forall> k \<ge> ma. f (xs @ [k]) = 0; ma \<le> w\<rbrakk>
       
   954     \<Longrightarrow> Sigma f (xs @ [w]) = ma"
       
   955 apply(induct w, auto)
       
   956 apply(rule_tac Sigma_0, simp)
       
   957 apply(simp add: Sigma_Suc_simp_rewrite)
       
   958 apply(case_tac "ma = Suc w", auto)
       
   959 done
       
   960 
       
   961 lemma Sigma_Max_lemma: 
       
   962   assumes prrf: "primerec rf (Suc (length xs))"
       
   963   shows "UF.Sigma (rec_exec (Cn (Suc (Suc (length xs))) rec_not
       
   964   [rec_all (recf.id (Suc (Suc (length xs))) (length xs))
       
   965   (Cn (Suc (Suc (Suc (length xs)))) rec_disj
       
   966   [Cn (Suc (Suc (Suc (length xs)))) rec_le
       
   967   [recf.id (Suc (Suc (Suc (length xs)))) (Suc (Suc (length xs))), 
       
   968   recf.id (Suc (Suc (Suc (length xs)))) (Suc (length xs))],
       
   969   Cn (Suc (Suc (Suc (length xs)))) rec_not
       
   970   [Cn (Suc (Suc (Suc (length xs)))) rf
       
   971   (get_fstn_args (Suc (Suc (Suc (length xs)))) (length xs) @ 
       
   972   [recf.id (Suc (Suc (Suc (length xs)))) (Suc (Suc (length xs)))])]])]))
       
   973   ((xs @ [w]) @ [w]) =
       
   974        Maxr (\<lambda>args. 0 < rec_exec rf args) xs w"
       
   975 proof -
       
   976   let ?rt = "(recf.id (Suc (Suc (length xs))) ((length xs)))"
       
   977   let ?rf1 = "Cn (Suc (Suc (Suc (length xs))))
       
   978     rec_le [recf.id (Suc (Suc (Suc (length xs)))) 
       
   979     ((Suc (Suc (length xs)))), recf.id 
       
   980     (Suc (Suc (Suc (length xs)))) ((Suc (length xs)))]"
       
   981   let ?rf2 = "Cn (Suc (Suc (Suc (length xs)))) rf 
       
   982                (get_fstn_args (Suc (Suc (Suc (length xs))))
       
   983     (length xs) @ 
       
   984     [recf.id (Suc (Suc (Suc (length xs))))    
       
   985     ((Suc (Suc (length xs))))])"
       
   986   let ?rf3 = "Cn (Suc (Suc (Suc (length xs)))) rec_not [?rf2]"
       
   987   let ?rf = "Cn (Suc (Suc (Suc (length xs)))) rec_disj [?rf1, ?rf3]"
       
   988   let ?rq = "rec_all ?rt ?rf"
       
   989   let ?notrq = "Cn (Suc (Suc (length xs))) rec_not [?rq]"
       
   990   show "?thesis"
       
   991   proof(auto simp: Maxr.simps)
       
   992     assume h: "\<forall>x\<le>w. rec_exec rf (xs @ [x]) = 0"
       
   993     have "primerec ?rf (Suc (length (xs @ [w, i]))) \<and> 
       
   994           primerec ?rt (length (xs @ [w, i]))"
       
   995       using prrf
       
   996       apply(auto)
       
   997       apply(case_tac i, auto)
       
   998       apply(case_tac ia, auto simp: h nth_append)
       
   999       done
       
  1000     hence "Sigma (rec_exec ?notrq) ((xs@[w])@[w]) = 0"
       
  1001       apply(rule_tac Sigma_0)
       
  1002       apply(auto simp: rec_exec.simps all_lemma
       
  1003                        get_fstn_args_take nth_append h)
       
  1004       done
       
  1005     thus "UF.Sigma (rec_exec ?notrq)
       
  1006       (xs @ [w, w]) = 0"
       
  1007       by simp
       
  1008   next
       
  1009     fix x
       
  1010     assume h: "x \<le> w" "0 < rec_exec rf (xs @ [x])"
       
  1011     hence "\<exists> ma. Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])} = ma"
       
  1012       by auto
       
  1013     from this obtain ma where k1: 
       
  1014       "Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])} = ma" ..
       
  1015     hence k2: "ma \<le> w \<and> 0 < rec_exec rf (xs @ [ma])"
       
  1016       using h
       
  1017       apply(subgoal_tac
       
  1018         "Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])} \<in>  {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])}")
       
  1019       apply(erule_tac CollectE, simp)
       
  1020       apply(rule_tac Max_in, auto)
       
  1021       done
       
  1022     hence k3: "\<forall> k < ma. (rec_exec ?notrq (xs @ [w, k]) = 1)"
       
  1023       apply(auto simp: nth_append)
       
  1024       apply(subgoal_tac "primerec ?rf (Suc (length (xs @ [w, k]))) \<and> 
       
  1025         primerec ?rt (length (xs @ [w, k]))")
       
  1026       apply(auto simp: rec_exec.simps all_lemma get_fstn_args_take nth_append)
       
  1027       using prrf
       
  1028       apply(case_tac i, auto)
       
  1029       apply(case_tac ia, auto simp: h nth_append)
       
  1030       done    
       
  1031     have k4: "\<forall> k \<ge> ma. (rec_exec ?notrq (xs @ [w, k]) = 0)"
       
  1032       apply(auto)
       
  1033       apply(subgoal_tac "primerec ?rf (Suc (length (xs @ [w, k]))) \<and> 
       
  1034         primerec ?rt (length (xs @ [w, k]))")
       
  1035       apply(auto simp: rec_exec.simps all_lemma get_fstn_args_take nth_append)
       
  1036       apply(subgoal_tac "x \<le> Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])}",
       
  1037         simp add: k1)
       
  1038       apply(rule_tac Max_ge, auto)
       
  1039       using prrf
       
  1040       apply(case_tac i, auto)
       
  1041       apply(case_tac ia, auto simp: h nth_append)
       
  1042       done 
       
  1043     from k3 k4 k1 have "Sigma (rec_exec ?notrq) ((xs @ [w]) @ [w]) = ma"
       
  1044       apply(rule_tac Sigma_max_point, simp, simp, simp add: k2)
       
  1045       done
       
  1046     from k1 and this show "Sigma (rec_exec ?notrq) (xs @ [w, w]) =
       
  1047       Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])}"
       
  1048       by simp
       
  1049   qed  
       
  1050 qed
       
  1051 
       
  1052 text {*
       
  1053   The correctness of @{text "rec_maxr"}.
       
  1054   *}
       
  1055 lemma Maxr_lemma:
       
  1056  assumes h: "primerec rf (Suc (length xs))"
       
  1057  shows   "rec_exec (rec_maxr rf) (xs @ [w]) = 
       
  1058             Maxr (\<lambda> args. 0 < rec_exec rf args) xs w"
       
  1059 proof -
       
  1060   from h have "arity rf = Suc (length xs)"
       
  1061     by auto
       
  1062   thus "?thesis"
       
  1063   proof(simp add: rec_exec.simps rec_maxr.simps nth_append get_fstn_args_take)
       
  1064     let ?rt = "(recf.id (Suc (Suc (length xs))) ((length xs)))"
       
  1065     let ?rf1 = "Cn (Suc (Suc (Suc (length xs))))
       
  1066                      rec_le [recf.id (Suc (Suc (Suc (length xs)))) 
       
  1067               ((Suc (Suc (length xs)))), recf.id 
       
  1068              (Suc (Suc (Suc (length xs)))) ((Suc (length xs)))]"
       
  1069     let ?rf2 = "Cn (Suc (Suc (Suc (length xs)))) rf 
       
  1070                (get_fstn_args (Suc (Suc (Suc (length xs))))
       
  1071                 (length xs) @ 
       
  1072                   [recf.id (Suc (Suc (Suc (length xs))))    
       
  1073                            ((Suc (Suc (length xs))))])"
       
  1074     let ?rf3 = "Cn (Suc (Suc (Suc (length xs)))) rec_not [?rf2]"
       
  1075     let ?rf = "Cn (Suc (Suc (Suc (length xs)))) rec_disj [?rf1, ?rf3]"
       
  1076     let ?rq = "rec_all ?rt ?rf"
       
  1077     let ?notrq = "Cn (Suc (Suc (length xs))) rec_not [?rq]"
       
  1078     have prt: "primerec ?rt (Suc (Suc (length xs)))"
       
  1079       by(auto intro: prime_id)
       
  1080     have prrf: "primerec ?rf (Suc (Suc (Suc (length xs))))"
       
  1081       apply(auto)
       
  1082       apply(case_tac i, auto)
       
  1083       apply(case_tac ia, auto intro: prime_id)
       
  1084       apply(simp add: h)
       
  1085       apply(simp add: nth_append, auto intro: prime_id)
       
  1086       done
       
  1087     from prt and prrf have prrq: "primerec ?rq 
       
  1088                                        (Suc (Suc (length xs)))"
       
  1089       by(erule_tac primerec_all_iff, auto)
       
  1090     hence prnotrp: "primerec ?notrq (Suc (length ((xs @ [w]))))"
       
  1091       by(rule_tac prime_cn, auto)
       
  1092     have g1: "rec_exec (rec_sigma ?notrq) ((xs @ [w]) @ [w]) 
       
  1093       = Maxr (\<lambda>args. 0 < rec_exec rf args) xs w"
       
  1094       using prnotrp
       
  1095       using sigma_lemma
       
  1096       apply(simp only: sigma_lemma)
       
  1097       apply(rule_tac Sigma_Max_lemma)
       
  1098       apply(simp add: h)
       
  1099       done
       
  1100     thus "rec_exec (rec_sigma ?notrq)
       
  1101      (xs @ [w, w]) =
       
  1102     Maxr (\<lambda>args. 0 < rec_exec rf args) xs w"
       
  1103       apply(simp)
       
  1104       done
       
  1105   qed
       
  1106 qed
       
  1107       
       
  1108 text {* 
       
  1109   @text "quo"} is the formal specification of division.
       
  1110  *}
       
  1111 fun quo :: "nat list \<Rightarrow> nat"
       
  1112   where
       
  1113   "quo [x, y] = (let Rr = 
       
  1114                          (\<lambda> zs. ((zs ! (Suc 0) * zs ! (Suc (Suc 0))
       
  1115                                  \<le> zs ! 0) \<and> zs ! Suc 0 \<noteq> (0::nat)))
       
  1116                  in Maxr Rr [x, y] x)"
       
  1117  
       
  1118 declare quo.simps[simp del]
       
  1119 
       
  1120 text {*
       
  1121   The following lemmas shows more directly the menaing of @{text "quo"}:
       
  1122   *}
       
  1123 lemma [elim!]: "y > 0 \<Longrightarrow> quo [x, y] = x div y"
       
  1124 proof(simp add: quo.simps Maxr.simps, auto,
       
  1125       rule_tac Max_eqI, simp, auto)
       
  1126   fix xa ya
       
  1127   assume h: "y * ya \<le> x"  "y > 0"
       
  1128   hence "(y * ya) div y \<le> x div y"
       
  1129     by(insert div_le_mono[of "y * ya" x y], simp)
       
  1130   from this and h show "ya \<le> x div y" by simp
       
  1131 next
       
  1132   fix xa
       
  1133   show "y * (x div y) \<le> x"
       
  1134     apply(subgoal_tac "y * (x div y) + x mod y = x")
       
  1135     apply(rule_tac k = "x mod y" in add_leD1, simp)
       
  1136     apply(simp)
       
  1137     done
       
  1138 qed
       
  1139 
       
  1140 lemma [intro]: "quo [x, 0] = 0"
       
  1141 by(simp add: quo.simps Maxr.simps)
       
  1142 
       
  1143 lemma quo_div: "quo [x, y] = x div y"  
       
  1144 by(case_tac "y=0", auto)
       
  1145 
       
  1146 text {*
       
  1147   @{text "rec_noteq"} is the recursive function testing whether its
       
  1148   two arguments are not equal.
       
  1149   *}
       
  1150 definition rec_noteq:: "recf"
       
  1151   where
       
  1152   "rec_noteq = Cn (Suc (Suc 0)) rec_not [Cn (Suc (Suc 0)) 
       
  1153               rec_eq [id (Suc (Suc 0)) (0), id (Suc (Suc 0)) 
       
  1154                                         ((Suc 0))]]"
       
  1155 
       
  1156 text {*
       
  1157   The correctness of @{text "rec_noteq"}.
       
  1158   *}
       
  1159 lemma noteq_lemma: 
       
  1160   "\<And> x y. rec_exec rec_noteq [x, y] = 
       
  1161                (if x \<noteq> y then 1 else 0)"
       
  1162 by(simp add: rec_exec.simps rec_noteq_def)
       
  1163 
       
  1164 declare noteq_lemma[simp]
       
  1165 
       
  1166 text {*
       
  1167   @{text "rec_quo"} is the recursive function used to implement @{text "quo"}
       
  1168   *}
       
  1169 definition rec_quo :: "recf"
       
  1170   where
       
  1171   "rec_quo = (let rR = Cn (Suc (Suc (Suc 0))) rec_conj
       
  1172               [Cn (Suc (Suc (Suc 0))) rec_le 
       
  1173                [Cn (Suc (Suc (Suc 0))) rec_mult 
       
  1174                   [id (Suc (Suc (Suc 0))) (Suc 0), 
       
  1175                      id (Suc (Suc (Suc 0))) ((Suc (Suc 0)))],
       
  1176                 id (Suc (Suc (Suc 0))) (0)], 
       
  1177                 Cn (Suc (Suc (Suc 0))) rec_noteq 
       
  1178                          [id (Suc (Suc (Suc 0))) (Suc (0)),
       
  1179                 Cn (Suc (Suc (Suc 0))) (constn 0) 
       
  1180                               [id (Suc (Suc (Suc 0))) (0)]]] 
       
  1181               in Cn (Suc (Suc 0)) (rec_maxr rR)) [id (Suc (Suc 0)) 
       
  1182                            (0),id (Suc (Suc 0)) (Suc (0)), 
       
  1183                                    id (Suc (Suc 0)) (0)]"
       
  1184 
       
  1185 lemma [intro]: "primerec rec_conj (Suc (Suc 0))"
       
  1186   apply(simp add: rec_conj_def)
       
  1187   apply(rule_tac prime_cn, auto)+
       
  1188   apply(case_tac i, auto intro: prime_id)
       
  1189   done
       
  1190 
       
  1191 lemma [intro]: "primerec rec_noteq (Suc (Suc 0))"
       
  1192 apply(simp add: rec_noteq_def)
       
  1193 apply(rule_tac prime_cn, auto)+
       
  1194 apply(case_tac i, auto intro: prime_id)
       
  1195 done
       
  1196 
       
  1197 
       
  1198 lemma quo_lemma1: "rec_exec rec_quo [x, y] = quo [x, y]"
       
  1199 proof(simp add: rec_exec.simps rec_quo_def)
       
  1200   let ?rR = "(Cn (Suc (Suc (Suc 0))) rec_conj
       
  1201                [Cn (Suc (Suc (Suc 0))) rec_le
       
  1202                    [Cn (Suc (Suc (Suc 0))) rec_mult 
       
  1203                [recf.id (Suc (Suc (Suc 0))) (Suc (0)), 
       
  1204                 recf.id (Suc (Suc (Suc 0))) (Suc (Suc (0)))],
       
  1205                  recf.id (Suc (Suc (Suc 0))) (0)],  
       
  1206           Cn (Suc (Suc (Suc 0))) rec_noteq 
       
  1207                               [recf.id (Suc (Suc (Suc 0))) 
       
  1208              (Suc (0)), Cn (Suc (Suc (Suc 0))) (constn 0) 
       
  1209                       [recf.id (Suc (Suc (Suc 0))) (0)]]])"
       
  1210   have "rec_exec (rec_maxr ?rR) ([x, y]@ [ x]) = Maxr (\<lambda> args. 0 < rec_exec ?rR args) [x, y] x"
       
  1211   proof(rule_tac Maxr_lemma, simp)
       
  1212     show "primerec ?rR (Suc (Suc (Suc 0)))"
       
  1213       apply(auto)
       
  1214       apply(case_tac i, auto)
       
  1215       apply(case_tac [!] ia, auto)
       
  1216       apply(case_tac i, auto)
       
  1217       done
       
  1218   qed
       
  1219   hence g1: "rec_exec (rec_maxr ?rR) ([x, y,  x]) =
       
  1220              Maxr (\<lambda> args. if rec_exec ?rR args = 0 then False
       
  1221                            else True) [x, y] x" 
       
  1222     by simp
       
  1223   have g2: "Maxr (\<lambda> args. if rec_exec ?rR args = 0 then False
       
  1224                            else True) [x, y] x = quo [x, y]"
       
  1225     apply(simp add: rec_exec.simps)
       
  1226     apply(simp add: Maxr.simps quo.simps, auto)
       
  1227     done
       
  1228   from g1 and g2 show 
       
  1229     "rec_exec (rec_maxr ?rR) ([x, y,  x]) = quo [x, y]"
       
  1230     by simp
       
  1231 qed
       
  1232 
       
  1233 text {*
       
  1234   The correctness of @{text "quo"}.
       
  1235   *}
       
  1236 lemma quo_lemma2: "rec_exec rec_quo [x, y] = x div y"
       
  1237   using quo_lemma1[of x y] quo_div[of x y]
       
  1238   by simp
       
  1239  
       
  1240 text {* 
       
  1241   @{text "rec_mod"} is the recursive function used to implement 
       
  1242   the reminder function.
       
  1243   *}
       
  1244 definition rec_mod :: "recf"
       
  1245   where
       
  1246   "rec_mod = Cn (Suc (Suc 0)) rec_minus [id (Suc (Suc 0)) (0), 
       
  1247                Cn (Suc (Suc 0)) rec_mult [rec_quo, id (Suc (Suc 0))
       
  1248                                                      (Suc (0))]]"
       
  1249 
       
  1250 text {*
       
  1251   The correctness of @{text "rec_mod"}:
       
  1252   *}
       
  1253 lemma mod_lemma: "\<And> x y. rec_exec rec_mod [x, y] = (x mod y)"
       
  1254 proof(simp add: rec_exec.simps rec_mod_def quo_lemma2)
       
  1255   fix x y
       
  1256   show "x - x div y * y = x mod (y::nat)"
       
  1257     using mod_div_equality2[of y x]
       
  1258     apply(subgoal_tac "y * (x div y) = (x div y ) * y", arith, simp)
       
  1259     done
       
  1260 qed
       
  1261 
       
  1262 text{* lemmas for embranch function*}
       
  1263 type_synonym ftype = "nat list \<Rightarrow> nat"
       
  1264 type_synonym rtype = "nat list \<Rightarrow> bool"
       
  1265 
       
  1266 text {*
       
  1267   The specifation of the mutli-way branching statement on
       
  1268   page 79 of Boolos's book.
       
  1269   *}
       
  1270 fun Embranch :: "(ftype * rtype) list \<Rightarrow> nat list \<Rightarrow> nat"
       
  1271   where
       
  1272   "Embranch [] xs = 0" |
       
  1273   "Embranch (gc # gcs) xs = (
       
  1274                    let (g, c) = gc in 
       
  1275                    if c xs then g xs else Embranch gcs xs)"
       
  1276 
       
  1277 fun rec_embranch' :: "(recf * recf) list \<Rightarrow> nat \<Rightarrow> recf"
       
  1278   where
       
  1279   "rec_embranch' [] vl = Cn vl z [id vl (vl - 1)]" |
       
  1280   "rec_embranch' ((rg, rc) # rgcs) vl = Cn vl rec_add
       
  1281                    [Cn vl rec_mult [rg, rc], rec_embranch' rgcs vl]"
       
  1282 
       
  1283 text {*
       
  1284   @{text "rec_embrach"} is the recursive function used to implement
       
  1285   @{text "Embranch"}.
       
  1286   *}
       
  1287 fun rec_embranch :: "(recf * recf) list \<Rightarrow> recf"
       
  1288   where
       
  1289   "rec_embranch ((rg, rc) # rgcs) = 
       
  1290          (let vl = arity rg in 
       
  1291           rec_embranch' ((rg, rc) # rgcs) vl)"
       
  1292 
       
  1293 declare Embranch.simps[simp del] rec_embranch.simps[simp del]
       
  1294 
       
  1295 lemma embranch_all0: 
       
  1296   "\<lbrakk>\<forall> j < length rcs. rec_exec (rcs ! j) xs = 0;
       
  1297     length rgs = length rcs;  
       
  1298   rcs \<noteq> []; 
       
  1299   list_all (\<lambda> rf. primerec rf (length xs)) (rgs @ rcs)\<rbrakk>  \<Longrightarrow> 
       
  1300   rec_exec (rec_embranch (zip rgs rcs)) xs = 0"
       
  1301 proof(induct rcs arbitrary: rgs, simp, case_tac rgs, simp)
       
  1302   fix a rcs rgs aa list
       
  1303   assume ind: 
       
  1304     "\<And>rgs. \<lbrakk>\<forall>j<length rcs. rec_exec (rcs ! j) xs = 0; 
       
  1305              length rgs = length rcs; rcs \<noteq> []; 
       
  1306             list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ rcs)\<rbrakk> \<Longrightarrow> 
       
  1307                       rec_exec (rec_embranch (zip rgs rcs)) xs = 0"
       
  1308   and h:  "\<forall>j<length (a # rcs). rec_exec ((a # rcs) ! j) xs = 0"
       
  1309   "length rgs = length (a # rcs)" 
       
  1310     "a # rcs \<noteq> []" 
       
  1311     "list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ a # rcs)"
       
  1312     "rgs = aa # list"
       
  1313   have g: "rcs \<noteq> [] \<Longrightarrow> rec_exec (rec_embranch (zip list rcs)) xs = 0"
       
  1314     using h
       
  1315     by(rule_tac ind, auto)
       
  1316   show "rec_exec (rec_embranch (zip rgs (a # rcs))) xs = 0"
       
  1317   proof(case_tac "rcs = []", simp)
       
  1318     show "rec_exec (rec_embranch (zip rgs [a])) xs = 0"
       
  1319       using h
       
  1320       apply(simp add: rec_embranch.simps rec_exec.simps)
       
  1321       apply(erule_tac x = 0 in allE, simp)
       
  1322       done
       
  1323   next
       
  1324     assume "rcs \<noteq> []"
       
  1325     hence "rec_exec (rec_embranch (zip list rcs)) xs = 0"
       
  1326       using g by simp
       
  1327     thus "rec_exec (rec_embranch (zip rgs (a # rcs))) xs = 0"
       
  1328       using h
       
  1329       apply(simp add: rec_embranch.simps rec_exec.simps)
       
  1330       apply(case_tac rcs,
       
  1331         auto simp: rec_exec.simps rec_embranch.simps)
       
  1332       apply(case_tac list,
       
  1333         auto simp: rec_exec.simps rec_embranch.simps)
       
  1334       done
       
  1335   qed
       
  1336 qed     
       
  1337  
       
  1338 
       
  1339 lemma embranch_exec_0: "\<lbrakk>rec_exec aa xs = 0; zip rgs list \<noteq> []; 
       
  1340        list_all (\<lambda> rf. primerec rf (length xs)) ([a, aa] @ rgs @ list)\<rbrakk>
       
  1341        \<Longrightarrow> rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs
       
  1342          = rec_exec (rec_embranch (zip rgs list)) xs"
       
  1343 apply(simp add: rec_exec.simps rec_embranch.simps)
       
  1344 apply(case_tac "zip rgs list", simp, case_tac ab, 
       
  1345   simp add: rec_embranch.simps rec_exec.simps)
       
  1346 apply(subgoal_tac "arity a = length xs", auto)
       
  1347 apply(subgoal_tac "arity aaa = length xs", auto)
       
  1348 apply(case_tac rgs, simp, case_tac list, simp, simp)
       
  1349 done
       
  1350 
       
  1351 lemma zip_null_iff: "\<lbrakk>length xs = k; length ys = k; zip xs ys = []\<rbrakk> \<Longrightarrow> xs = [] \<and> ys = []"
       
  1352 apply(case_tac xs, simp, simp)
       
  1353 apply(case_tac ys, simp, simp)
       
  1354 done
       
  1355 
       
  1356 lemma zip_null_gr: "\<lbrakk>length xs = k; length ys = k; zip xs ys \<noteq> []\<rbrakk> \<Longrightarrow> 0 < k"
       
  1357 apply(case_tac xs, simp, simp)
       
  1358 done
       
  1359 
       
  1360 lemma Embranch_0:  
       
  1361   "\<lbrakk>length rgs = k; length rcs = k; k > 0; 
       
  1362   \<forall> j < k. rec_exec (rcs ! j) xs = 0\<rbrakk> \<Longrightarrow>
       
  1363   Embranch (zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs = 0"
       
  1364 proof(induct rgs arbitrary: rcs k, simp, simp)
       
  1365   fix a rgs rcs k
       
  1366   assume ind: 
       
  1367     "\<And>rcs k. \<lbrakk>length rgs = k; length rcs = k; 0 < k; \<forall>j<k. rec_exec (rcs ! j) xs = 0\<rbrakk> 
       
  1368     \<Longrightarrow> Embranch (zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs = 0"
       
  1369   and h: "Suc (length rgs) = k" "length rcs = k"
       
  1370     "\<forall>j<k. rec_exec (rcs ! j) xs = 0"
       
  1371   from h show  
       
  1372     "Embranch (zip (rec_exec a # map rec_exec rgs) 
       
  1373            (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs = 0"
       
  1374     apply(case_tac rcs, simp, case_tac "rgs = []", simp)
       
  1375     apply(simp add: Embranch.simps)
       
  1376     apply(erule_tac x = 0 in allE, simp)
       
  1377     apply(simp add: Embranch.simps)
       
  1378     apply(erule_tac x = 0 in all_dupE, simp)
       
  1379     apply(rule_tac ind, simp, simp, simp, auto)
       
  1380     apply(erule_tac x = "Suc j" in allE, simp)
       
  1381     done
       
  1382 qed
       
  1383 
       
  1384 text {*
       
  1385   The correctness of @{text "rec_embranch"}.
       
  1386   *}
       
  1387 lemma embranch_lemma:
       
  1388   assumes branch_num:
       
  1389   "length rgs = n" "length rcs = n" "n > 0"
       
  1390   and partition: 
       
  1391   "(\<exists> i < n. (rec_exec (rcs ! i) xs = 1 \<and> (\<forall> j < n. j \<noteq> i \<longrightarrow> 
       
  1392                                       rec_exec (rcs ! j) xs = 0)))"
       
  1393   and prime_all: "list_all (\<lambda> rf. primerec rf (length xs)) (rgs @ rcs)"
       
  1394   shows "rec_exec (rec_embranch (zip rgs rcs)) xs =
       
  1395                   Embranch (zip (map rec_exec rgs) 
       
  1396                      (map (\<lambda> r args. 0 < rec_exec r args) rcs)) xs"
       
  1397   using branch_num partition prime_all
       
  1398 proof(induct rgs arbitrary: rcs n, simp)
       
  1399   fix a rgs rcs n
       
  1400   assume ind: 
       
  1401     "\<And>rcs n. \<lbrakk>length rgs = n; length rcs = n; 0 < n;
       
  1402     \<exists>i<n. rec_exec (rcs ! i) xs = 1 \<and> (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec (rcs ! j) xs = 0);
       
  1403     list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ rcs)\<rbrakk>
       
  1404     \<Longrightarrow> rec_exec (rec_embranch (zip rgs rcs)) xs =
       
  1405     Embranch (zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs"
       
  1406   and h: "length (a # rgs) = n" "length (rcs::recf list) = n" "0 < n"
       
  1407          " \<exists>i<n. rec_exec (rcs ! i) xs = 1 \<and> 
       
  1408          (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec (rcs ! j) xs = 0)" 
       
  1409     "list_all (\<lambda>rf. primerec rf (length xs)) ((a # rgs) @ rcs)"
       
  1410   from h show "rec_exec (rec_embranch (zip (a # rgs) rcs)) xs =
       
  1411     Embranch (zip (map rec_exec (a # rgs)) (map (\<lambda>r args. 
       
  1412                 0 < rec_exec r args) rcs)) xs"
       
  1413     apply(case_tac rcs, simp, simp)
       
  1414     apply(case_tac "rec_exec aa xs = 0")
       
  1415     apply(case_tac [!] "zip rgs list = []", simp)
       
  1416     apply(subgoal_tac "rgs = [] \<and> list = []", simp add: Embranch.simps rec_exec.simps rec_embranch.simps)
       
  1417     apply(rule_tac  zip_null_iff, simp, simp, simp)
       
  1418 thm Embranch.simps
       
  1419   proof -
       
  1420     fix aa list
       
  1421     assume g:
       
  1422       "Suc (length rgs) = n" "Suc (length list) = n" 
       
  1423       "\<exists>i<n. rec_exec ((aa # list) ! i) xs = Suc 0 \<and> 
       
  1424           (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec ((aa # list) ! j) xs = 0)"
       
  1425       "primerec a (length xs) \<and> 
       
  1426       list_all (\<lambda>rf. primerec rf (length xs)) rgs \<and>
       
  1427       primerec aa (length xs) \<and> 
       
  1428       list_all (\<lambda>rf. primerec rf (length xs)) list"
       
  1429       "rec_exec aa xs = 0" "rcs = aa # list" "zip rgs list \<noteq> []"
       
  1430     have "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs
       
  1431         = rec_exec (rec_embranch (zip rgs list)) xs"
       
  1432       apply(rule embranch_exec_0, simp_all add: g)
       
  1433       done
       
  1434     from g and this show "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs =
       
  1435          Embranch ((rec_exec a, \<lambda>args. 0 < rec_exec aa args) # 
       
  1436            zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) list)) xs"
       
  1437       apply(simp add: Embranch.simps)
       
  1438       apply(rule_tac n = "n - Suc 0" in ind)
       
  1439       apply(case_tac n, simp, simp)
       
  1440       apply(case_tac n, simp, simp)
       
  1441       apply(case_tac n, simp, simp add: zip_null_gr )
       
  1442       apply(auto)
       
  1443       apply(case_tac i, simp, simp)
       
  1444       apply(rule_tac x = nat in exI, simp)
       
  1445       apply(rule_tac allI, erule_tac x = "Suc j" in allE, simp)
       
  1446       done
       
  1447   next
       
  1448     fix aa list
       
  1449     assume g: "Suc (length rgs) = n" "Suc (length list) = n"
       
  1450       "\<exists>i<n. rec_exec ((aa # list) ! i) xs = Suc 0 \<and> 
       
  1451       (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec ((aa # list) ! j) xs = 0)"
       
  1452       "primerec a (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) rgs \<and>
       
  1453       primerec aa (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) list"
       
  1454     "rcs = aa # list" "rec_exec aa xs \<noteq> 0" "zip rgs list = []"
       
  1455     thus "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs = 
       
  1456         Embranch ((rec_exec a, \<lambda>args. 0 < rec_exec aa args) # 
       
  1457        zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) list)) xs"
       
  1458       apply(subgoal_tac "rgs = [] \<and> list = []", simp)
       
  1459       prefer 2
       
  1460       apply(rule_tac zip_null_iff, simp, simp, simp)
       
  1461       apply(simp add: rec_exec.simps rec_embranch.simps Embranch.simps, auto)
       
  1462       done
       
  1463   next
       
  1464     fix aa list
       
  1465     assume g: "Suc (length rgs) = n" "Suc (length list) = n"
       
  1466       "\<exists>i<n. rec_exec ((aa # list) ! i) xs = Suc 0 \<and>  
       
  1467            (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec ((aa # list) ! j) xs = 0)"
       
  1468       "primerec a (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) rgs
       
  1469       \<and> primerec aa (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) list"
       
  1470       "rcs = aa # list" "rec_exec aa xs \<noteq> 0" "zip rgs list \<noteq> []"
       
  1471     have "rec_exec aa xs =  Suc 0"
       
  1472       using g
       
  1473       apply(case_tac "rec_exec aa xs", simp, auto)
       
  1474       done      
       
  1475     moreover have "rec_exec (rec_embranch' (zip rgs list) (length xs)) xs = 0"
       
  1476     proof -
       
  1477       have "rec_embranch' (zip rgs list) (length xs) = rec_embranch (zip rgs list)"
       
  1478         using g
       
  1479         apply(case_tac "zip rgs list", simp, case_tac ab)
       
  1480         apply(simp add: rec_embranch.simps)
       
  1481         apply(subgoal_tac "arity aaa = length xs", simp, auto)
       
  1482         apply(case_tac rgs, simp, simp, case_tac list, simp, simp)
       
  1483         done
       
  1484       moreover have "rec_exec (rec_embranch (zip rgs list)) xs = 0"
       
  1485       proof(rule embranch_all0)
       
  1486         show " \<forall>j<length list. rec_exec (list ! j) xs = 0"
       
  1487           using g
       
  1488           apply(auto)
       
  1489           apply(case_tac i, simp)
       
  1490           apply(erule_tac x = "Suc j" in allE, simp)
       
  1491           apply(simp)
       
  1492           apply(erule_tac x = 0 in allE, simp)
       
  1493           done
       
  1494       next
       
  1495         show "length rgs = length list"
       
  1496           using g
       
  1497           apply(case_tac n, simp, simp)
       
  1498           done
       
  1499       next
       
  1500         show "list \<noteq> []"
       
  1501           using g
       
  1502           apply(case_tac list, simp, simp)
       
  1503           done
       
  1504       next
       
  1505         show "list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ list)"
       
  1506           using g
       
  1507           apply auto
       
  1508           done
       
  1509       qed
       
  1510       ultimately show "rec_exec (rec_embranch' (zip rgs list) (length xs)) xs = 0"
       
  1511         by simp
       
  1512     qed
       
  1513     moreover have 
       
  1514       "Embranch (zip (map rec_exec rgs) 
       
  1515           (map (\<lambda>r args. 0 < rec_exec r args) list)) xs = 0"
       
  1516       using g
       
  1517       apply(rule_tac k = "length rgs" in Embranch_0)
       
  1518       apply(simp, case_tac n, simp, simp)
       
  1519       apply(case_tac rgs, simp, simp)
       
  1520       apply(auto)
       
  1521       apply(case_tac i, simp)
       
  1522       apply(erule_tac x = "Suc j" in allE, simp)
       
  1523       apply(simp)
       
  1524       apply(rule_tac x = 0 in allE, auto)
       
  1525       done
       
  1526     moreover have "arity a = length xs"
       
  1527       using g
       
  1528       apply(auto)
       
  1529       done
       
  1530     ultimately show "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs = 
       
  1531       Embranch ((rec_exec a, \<lambda>args. 0 < rec_exec aa args) #
       
  1532            zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) list)) xs"
       
  1533       apply(simp add: rec_exec.simps rec_embranch.simps Embranch.simps)
       
  1534       done
       
  1535   qed
       
  1536 qed
       
  1537 
       
  1538 text{* 
       
  1539   @{text "prime n"} means @{text "n"} is a prime number.
       
  1540 *}
       
  1541 fun Prime :: "nat \<Rightarrow> bool"
       
  1542   where
       
  1543   "Prime x = (1 < x \<and> (\<forall> u < x. (\<forall> v < x. u * v \<noteq> x)))"
       
  1544 
       
  1545 declare Prime.simps [simp del]
       
  1546 
       
  1547 lemma primerec_all1: 
       
  1548   "primerec (rec_all rt rf) n \<Longrightarrow> primerec rt n"
       
  1549   by (simp add: primerec_all)
       
  1550 
       
  1551 lemma primerec_all2: "primerec (rec_all rt rf) n \<Longrightarrow> 
       
  1552   primerec rf (Suc n)"
       
  1553 by(insert primerec_all[of rt rf n], simp)
       
  1554 
       
  1555 text {*
       
  1556   @{text "rec_prime"} is the recursive function used to implement
       
  1557   @{text "Prime"}.
       
  1558   *}
       
  1559 definition rec_prime :: "recf"
       
  1560   where
       
  1561   "rec_prime = Cn (Suc 0) rec_conj 
       
  1562   [Cn (Suc 0) rec_less [constn 1, id (Suc 0) (0)],
       
  1563         rec_all (Cn 1 rec_minus [id 1 0, constn 1]) 
       
  1564        (rec_all (Cn 2 rec_minus [id 2 0, Cn 2 (constn 1) 
       
  1565   [id 2 0]]) (Cn 3 rec_noteq 
       
  1566        [Cn 3 rec_mult [id 3 1, id 3 2], id 3 0]))]"
       
  1567 
       
  1568 (*
       
  1569 lemma prime_lemma1: 
       
  1570   "(rec_exec rec_prime [x] = Suc 0) \<or> 
       
  1571   (rec_exec rec_prime [x] = 0)"
       
  1572 apply(auto simp: rec_exec.simps rec_prime_def)
       
  1573 done
       
  1574 *)
       
  1575 declare numeral_2_eq_2[simp del] numeral_3_eq_3[simp del]
       
  1576 
       
  1577 lemma exec_tmp: 
       
  1578   "rec_exec (rec_all (Cn 2 rec_minus [recf.id 2 0, Cn 2 (constn (Suc 0)) [recf.id 2 0]]) 
       
  1579   (Cn 3 rec_noteq [Cn 3 rec_mult [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0]))  [x, k] = 
       
  1580   ((if (\<forall>w\<le>rec_exec (Cn 2 rec_minus [recf.id 2 0, Cn 2 (constn (Suc 0)) [recf.id 2 0]]) ([x, k]). 
       
  1581   0 < rec_exec (Cn 3 rec_noteq [Cn 3 rec_mult [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0])
       
  1582   ([x, k] @ [w])) then 1 else 0))"
       
  1583 apply(rule_tac all_lemma)
       
  1584 apply(auto)
       
  1585 apply(case_tac [!] i, auto)
       
  1586 apply(case_tac ia, auto simp: numeral_3_eq_3 numeral_2_eq_2)
       
  1587 done
       
  1588 
       
  1589 text {*
       
  1590   The correctness of @{text "Prime"}.
       
  1591   *}
       
  1592 lemma prime_lemma: "rec_exec rec_prime [x] = (if Prime x then 1 else 0)"
       
  1593 proof(simp add: rec_exec.simps rec_prime_def)
       
  1594   let ?rt1 = "(Cn 2 rec_minus [recf.id 2 0, 
       
  1595     Cn 2 (constn (Suc 0)) [recf.id 2 0]])"
       
  1596   let ?rf1 = "(Cn 3 rec_noteq [Cn 3 rec_mult 
       
  1597     [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 (0)])"
       
  1598   let ?rt2 = "(Cn (Suc 0) rec_minus 
       
  1599     [recf.id (Suc 0) 0, constn (Suc 0)])"
       
  1600   let ?rf2 = "rec_all ?rt1 ?rf1"
       
  1601   have h1: "rec_exec (rec_all ?rt2 ?rf2) ([x]) = 
       
  1602         (if (\<forall>k\<le>rec_exec ?rt2 ([x]). 0 < rec_exec ?rf2 ([x] @ [k])) then 1 else 0)"
       
  1603   proof(rule_tac all_lemma, simp_all)
       
  1604     show "primerec ?rf2 (Suc (Suc 0))"
       
  1605       apply(rule_tac primerec_all_iff)
       
  1606       apply(auto)
       
  1607       apply(case_tac [!] i, auto simp: numeral_2_eq_2)
       
  1608       apply(case_tac ia, auto simp: numeral_3_eq_3)
       
  1609       done
       
  1610   next
       
  1611     show "primerec (Cn (Suc 0) rec_minus
       
  1612              [recf.id (Suc 0) 0, constn (Suc 0)]) (Suc 0)"
       
  1613       apply(auto)
       
  1614       apply(case_tac i, auto)
       
  1615       done
       
  1616   qed
       
  1617   from h1 show 
       
  1618    "(Suc 0 < x \<longrightarrow>  (rec_exec (rec_all ?rt2 ?rf2) [x] = 0 \<longrightarrow> 
       
  1619     \<not> Prime x) \<and>
       
  1620      (0 < rec_exec (rec_all ?rt2 ?rf2) [x] \<longrightarrow> Prime x)) \<and>
       
  1621     (\<not> Suc 0 < x \<longrightarrow> \<not> Prime x \<and> (rec_exec (rec_all ?rt2 ?rf2) [x] = 0
       
  1622     \<longrightarrow> \<not> Prime x))"
       
  1623     apply(auto simp:rec_exec.simps)
       
  1624     apply(simp add: exec_tmp rec_exec.simps)
       
  1625   proof -
       
  1626     assume "\<forall>k\<le>x - Suc 0. (0::nat) < (if \<forall>w\<le>x - Suc 0. 
       
  1627            0 < (if k * w \<noteq> x then 1 else (0 :: nat)) then 1 else 0)" "Suc 0 < x"
       
  1628     thus "Prime x"
       
  1629       apply(simp add: rec_exec.simps split: if_splits)
       
  1630       apply(simp add: Prime.simps, auto)
       
  1631       apply(erule_tac x = u in allE, auto)
       
  1632       apply(case_tac u, simp, case_tac nat, simp, simp)
       
  1633       apply(case_tac v, simp, case_tac nat, simp, simp)
       
  1634       done
       
  1635   next
       
  1636     assume "\<not> Suc 0 < x" "Prime x"
       
  1637     thus "False"
       
  1638       apply(simp add: Prime.simps)
       
  1639       done
       
  1640   next
       
  1641     fix k
       
  1642     assume "rec_exec (rec_all ?rt1 ?rf1)
       
  1643       [x, k] = 0" "k \<le> x - Suc 0" "Prime x"
       
  1644     thus "False"
       
  1645       apply(simp add: exec_tmp rec_exec.simps Prime.simps split: if_splits)
       
  1646       done
       
  1647   next
       
  1648     fix k
       
  1649     assume "rec_exec (rec_all ?rt1 ?rf1)
       
  1650       [x, k] = 0" "k \<le> x - Suc 0" "Prime x"
       
  1651     thus "False"
       
  1652       apply(simp add: exec_tmp rec_exec.simps Prime.simps split: if_splits)
       
  1653       done
       
  1654   qed
       
  1655 qed
       
  1656 
       
  1657 definition rec_dummyfac :: "recf"
       
  1658   where
       
  1659   "rec_dummyfac = Pr 1 (constn 1) 
       
  1660   (Cn 3 rec_mult [id 3 2, Cn 3 s [id 3 1]])"
       
  1661 
       
  1662 text {*
       
  1663   The recursive function used to implment factorization.
       
  1664   *}
       
  1665 definition rec_fac :: "recf"
       
  1666   where
       
  1667   "rec_fac = Cn 1 rec_dummyfac [id 1 0, id 1 0]"
       
  1668 
       
  1669 text {*
       
  1670   Formal specification of factorization.
       
  1671   *}
       
  1672 fun fac :: "nat \<Rightarrow> nat"  ("_!" [100] 99)
       
  1673   where
       
  1674   "fac 0 = 1" |
       
  1675   "fac (Suc x) = (Suc x) * fac x"
       
  1676 
       
  1677 lemma [simp]: "rec_exec rec_dummyfac [0, 0] = Suc 0"
       
  1678 by(simp add: rec_dummyfac_def rec_exec.simps)
       
  1679 
       
  1680 lemma rec_cn_simp: "rec_exec (Cn n f gs) xs = 
       
  1681                 (let rgs = map (\<lambda> g. rec_exec g xs) gs in
       
  1682                  rec_exec f rgs)"
       
  1683 by(simp add: rec_exec.simps)
       
  1684 
       
  1685 lemma rec_id_simp: "rec_exec (id m n) xs = xs ! n" 
       
  1686   by(simp add: rec_exec.simps)
       
  1687 
       
  1688 lemma fac_dummy: "rec_exec rec_dummyfac [x, y] = y !"
       
  1689 apply(induct y)
       
  1690 apply(auto simp: rec_dummyfac_def rec_exec.simps)
       
  1691 done
       
  1692 
       
  1693 text {*
       
  1694   The correctness of @{text "rec_fac"}.
       
  1695   *}
       
  1696 lemma fac_lemma: "rec_exec rec_fac [x] =  x!"
       
  1697 apply(simp add: rec_fac_def rec_exec.simps fac_dummy)
       
  1698 done
       
  1699 
       
  1700 declare fac.simps[simp del]
       
  1701 
       
  1702 text {*
       
  1703   @{text "Np x"} returns the first prime number after @{text "x"}.
       
  1704   *}
       
  1705 fun Np ::"nat \<Rightarrow> nat"
       
  1706   where
       
  1707   "Np x = Min {y. y \<le> Suc (x!) \<and> x < y \<and> Prime y}"
       
  1708 
       
  1709 declare Np.simps[simp del] rec_Minr.simps[simp del]
       
  1710 
       
  1711 text {*
       
  1712   @{text "rec_np"} is the recursive function used to implement
       
  1713   @{text "Np"}.
       
  1714   *}
       
  1715 definition rec_np :: "recf"
       
  1716   where
       
  1717   "rec_np = (let Rr = Cn 2 rec_conj [Cn 2 rec_less [id 2 0, id 2 1], 
       
  1718   Cn 2 rec_prime [id 2 1]]
       
  1719              in Cn 1 (rec_Minr Rr) [id 1 0, Cn 1 s [rec_fac]])"
       
  1720 
       
  1721 lemma [simp]: "n < Suc (n!)"
       
  1722 apply(induct n, simp)
       
  1723 apply(simp add: fac.simps)
       
  1724 apply(case_tac n, auto simp: fac.simps)
       
  1725 done
       
  1726 
       
  1727 lemma divsor_ex: 
       
  1728 "\<lbrakk>\<not> Prime x; x > Suc 0\<rbrakk> \<Longrightarrow> (\<exists> u > Suc 0. (\<exists> v > Suc 0. u * v = x))"
       
  1729  by(auto simp: Prime.simps)
       
  1730 
       
  1731 lemma divsor_prime_ex: "\<lbrakk>\<not> Prime x; x > Suc 0\<rbrakk> \<Longrightarrow> 
       
  1732   \<exists> p. Prime p \<and> p dvd x"
       
  1733 apply(induct x rule: wf_induct[where r = "measure (\<lambda> y. y)"], simp)
       
  1734 apply(drule_tac divsor_ex, simp, auto)
       
  1735 apply(erule_tac x = u in allE, simp)
       
  1736 apply(case_tac "Prime u", simp)
       
  1737 apply(rule_tac x = u in exI, simp, auto)
       
  1738 done
       
  1739 
       
  1740 lemma [intro]: "0 < n!"
       
  1741 apply(induct n)
       
  1742 apply(auto simp: fac.simps)
       
  1743 done
       
  1744 
       
  1745 lemma fac_Suc: "Suc n! =  (Suc n) * (n!)" by(simp add: fac.simps)
       
  1746 
       
  1747 lemma fac_dvd: "\<lbrakk>0 < q; q \<le> n\<rbrakk> \<Longrightarrow> q dvd n!"
       
  1748 apply(induct n, simp)
       
  1749 apply(case_tac "q \<le> n", simp add: fac_Suc)
       
  1750 apply(subgoal_tac "q = Suc n", simp only: fac_Suc)
       
  1751 apply(rule_tac dvd_mult2, simp, simp)
       
  1752 done
       
  1753 
       
  1754 lemma fac_dvd2: "\<lbrakk>Suc 0 < q; q dvd n!; q \<le> n\<rbrakk> \<Longrightarrow> \<not> q dvd Suc (n!)"
       
  1755 proof(auto simp: dvd_def)
       
  1756   fix k ka
       
  1757   assume h1: "Suc 0 < q" "q \<le> n"
       
  1758   and h2: "Suc (q * k) = q * ka"
       
  1759   have "k < ka"
       
  1760   proof - 
       
  1761     have "q * k < q * ka" 
       
  1762       using h2 by arith
       
  1763     thus "k < ka"
       
  1764       using h1
       
  1765       by(auto)
       
  1766   qed
       
  1767   hence "\<exists>d. d > 0 \<and>  ka = d + k"  
       
  1768     by(rule_tac x = "ka - k" in exI, simp)
       
  1769   from this obtain d where "d > 0 \<and> ka = d + k" ..
       
  1770   from h2 and this and h1 show "False"
       
  1771     by(simp add: add_mult_distrib2)
       
  1772 qed
       
  1773     
       
  1774 lemma prime_ex: "\<exists> p. n < p \<and> p \<le> Suc (n!) \<and> Prime p"
       
  1775 proof(cases "Prime (n! + 1)")
       
  1776   case True thus "?thesis" 
       
  1777     by(rule_tac x = "Suc (n!)" in exI, simp)
       
  1778 next
       
  1779   assume h: "\<not> Prime (n! + 1)"  
       
  1780   hence "\<exists> p. Prime p \<and> p dvd (n! + 1)"
       
  1781     by(erule_tac divsor_prime_ex, auto)
       
  1782   from this obtain q where k: "Prime q \<and> q dvd (n! + 1)" ..
       
  1783   thus "?thesis"
       
  1784   proof(cases "q > n")
       
  1785     case True thus "?thesis"
       
  1786       using k
       
  1787       apply(rule_tac x = q in exI, auto)
       
  1788       apply(rule_tac dvd_imp_le, auto)
       
  1789       done
       
  1790   next
       
  1791     case False thus "?thesis"
       
  1792     proof -
       
  1793       assume g: "\<not> n < q"
       
  1794       have j: "q > Suc 0"
       
  1795         using k by(case_tac q, auto simp: Prime.simps)
       
  1796       hence "q dvd n!"
       
  1797         using g 
       
  1798         apply(rule_tac fac_dvd, auto)
       
  1799         done
       
  1800       hence "\<not> q dvd Suc (n!)"
       
  1801         using g j
       
  1802         by(rule_tac fac_dvd2, auto)
       
  1803       thus "?thesis"
       
  1804         using k by simp
       
  1805     qed
       
  1806   qed
       
  1807 qed
       
  1808   
       
  1809 lemma Suc_Suc_induct[elim!]: "\<lbrakk>i < Suc (Suc 0); 
       
  1810   primerec (ys ! 0) n; primerec (ys ! 1) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n"
       
  1811 by(case_tac i, auto)
       
  1812 
       
  1813 lemma [intro]: "primerec rec_prime (Suc 0)"
       
  1814 apply(auto simp: rec_prime_def, auto)
       
  1815 apply(rule_tac primerec_all_iff, auto, auto)
       
  1816 apply(rule_tac primerec_all_iff, auto, auto simp:  
       
  1817   numeral_2_eq_2 numeral_3_eq_3)
       
  1818 done
       
  1819 
       
  1820 text {*
       
  1821   The correctness of @{text "rec_np"}.
       
  1822   *}
       
  1823 lemma np_lemma: "rec_exec rec_np [x] = Np x"
       
  1824 proof(auto simp: rec_np_def rec_exec.simps Let_def fac_lemma)
       
  1825   let ?rr = "(Cn 2 rec_conj [Cn 2 rec_less [recf.id 2 0,
       
  1826     recf.id 2 (Suc 0)], Cn 2 rec_prime [recf.id 2 (Suc 0)]])"
       
  1827   let ?R = "\<lambda> zs. zs ! 0 < zs ! 1 \<and> Prime (zs ! 1)"
       
  1828   have g1: "rec_exec (rec_Minr ?rr) ([x] @ [Suc (x!)]) = 
       
  1829     Minr (\<lambda> args. 0 < rec_exec ?rr args) [x] (Suc (x!))"
       
  1830     by(rule_tac Minr_lemma, auto simp: rec_exec.simps
       
  1831       prime_lemma, auto simp:  numeral_2_eq_2 numeral_3_eq_3)
       
  1832   have g2: "Minr (\<lambda> args. 0 < rec_exec ?rr args) [x] (Suc (x!)) = Np x"
       
  1833     using prime_ex[of x]
       
  1834     apply(auto simp: Minr.simps Np.simps rec_exec.simps)
       
  1835     apply(erule_tac x = p in allE, simp add: prime_lemma)
       
  1836     apply(simp add: prime_lemma split: if_splits)
       
  1837     apply(subgoal_tac
       
  1838    "{uu. (Prime uu \<longrightarrow> (x < uu \<longrightarrow> uu \<le> Suc (x!)) \<and> x < uu) \<and> Prime uu}
       
  1839     = {y. y \<le> Suc (x!) \<and> x < y \<and> Prime y}", auto)
       
  1840     done
       
  1841   from g1 and g2 show "rec_exec (rec_Minr ?rr) ([x, Suc (x!)]) = Np x"
       
  1842     by simp
       
  1843 qed
       
  1844 
       
  1845 text {*lemmas for power*}
       
  1846 text {*
       
  1847   @{text "rec_power"} is the recursive function used to implement
       
  1848   power function.
       
  1849   *}
       
  1850 definition rec_power :: "recf"
       
  1851   where
       
  1852   "rec_power = Pr 1 (constn 1) (Cn 3 rec_mult [id 3 0, id 3 2])"
       
  1853 
       
  1854 text {*
       
  1855   The correctness of @{text "rec_power"}.
       
  1856   *}
       
  1857 lemma power_lemma: "rec_exec rec_power [x, y] = x^y"
       
  1858   by(induct y, auto simp: rec_exec.simps rec_power_def)
       
  1859 
       
  1860 text{*
       
  1861   @{text "Pi k"} returns the @{text "k"}-th prime number.
       
  1862   *}
       
  1863 fun Pi :: "nat \<Rightarrow> nat"
       
  1864   where
       
  1865   "Pi 0 = 2" |
       
  1866   "Pi (Suc x) = Np (Pi x)"
       
  1867 
       
  1868 definition rec_dummy_pi :: "recf"
       
  1869   where
       
  1870   "rec_dummy_pi = Pr 1 (constn 2) (Cn 3 rec_np [id 3 2])"
       
  1871 
       
  1872 text {*
       
  1873   @{text "rec_pi"} is the recursive function used to implement
       
  1874   @{text "Pi"}.
       
  1875   *}
       
  1876 definition rec_pi :: "recf"
       
  1877   where
       
  1878   "rec_pi = Cn 1 rec_dummy_pi [id 1 0, id 1 0]"
       
  1879 
       
  1880 lemma pi_dummy_lemma: "rec_exec rec_dummy_pi [x, y] = Pi y"
       
  1881 apply(induct y)
       
  1882 by(auto simp: rec_exec.simps rec_dummy_pi_def Pi.simps np_lemma)
       
  1883 
       
  1884 text {*
       
  1885   The correctness of @{text "rec_pi"}.
       
  1886   *}
       
  1887 lemma pi_lemma: "rec_exec rec_pi [x] = Pi x"
       
  1888 apply(simp add: rec_pi_def rec_exec.simps pi_dummy_lemma)
       
  1889 done
       
  1890 
       
  1891 text{*follows: lemmas for lo*}
       
  1892 fun loR :: "nat list \<Rightarrow> bool"
       
  1893   where
       
  1894   "loR [x, y, u] = (x mod (y^u) = 0)"
       
  1895 
       
  1896 declare loR.simps[simp del]
       
  1897 
       
  1898 text {*
       
  1899   @{text "Lo"} specifies the @{text "lo"} function given on page 79 of 
       
  1900   Boolos's book. It is one of the two notions of integeral logarithmatic
       
  1901   operation on that page. The other is @{text "lg"}.
       
  1902   *}
       
  1903 fun lo :: " nat \<Rightarrow> nat \<Rightarrow> nat"
       
  1904   where 
       
  1905   "lo x y  = (if x > 1 \<and> y > 1 \<and> {u. loR [x, y, u]} \<noteq> {} then Max {u. loR [x, y, u]}
       
  1906                                                          else 0)"
       
  1907 
       
  1908 declare lo.simps[simp del]
       
  1909 
       
  1910 lemma [elim]: "primerec rf n \<Longrightarrow> n > 0"
       
  1911 apply(induct rule: primerec.induct, auto)
       
  1912 done
       
  1913 
       
  1914 lemma primerec_sigma[intro!]:  
       
  1915   "\<lbrakk>n > Suc 0; primerec rf n\<rbrakk> \<Longrightarrow> 
       
  1916   primerec (rec_sigma rf) n"
       
  1917 apply(simp add: rec_sigma.simps)
       
  1918 apply(auto, auto simp: nth_append)
       
  1919 done
       
  1920 
       
  1921 lemma [intro!]:  "\<lbrakk>primerec rf n; n > 0\<rbrakk> \<Longrightarrow> primerec (rec_maxr rf) n"
       
  1922 apply(simp add: rec_maxr.simps)
       
  1923 apply(rule_tac prime_cn, auto)
       
  1924 apply(rule_tac primerec_all_iff, auto, auto simp: nth_append)
       
  1925 done
       
  1926 
       
  1927 lemma Suc_Suc_Suc_induct[elim!]: 
       
  1928   "\<lbrakk>i < Suc (Suc (Suc (0::nat))); primerec (ys ! 0) n;
       
  1929   primerec (ys ! 1) n;  
       
  1930   primerec (ys ! 2) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n"
       
  1931 apply(case_tac i, auto, case_tac nat, simp, simp add: numeral_2_eq_2)
       
  1932 done
       
  1933 
       
  1934 lemma [intro]: "primerec rec_quo (Suc (Suc 0))"
       
  1935 apply(simp add: rec_quo_def)
       
  1936 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  1937     @{thm prime_id}] 1*}, auto+)+
       
  1938 done
       
  1939 
       
  1940 lemma [intro]: "primerec rec_mod (Suc (Suc 0))"
       
  1941 apply(simp add: rec_mod_def)
       
  1942 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  1943     @{thm prime_id}] 1*}, auto+)+
       
  1944 done
       
  1945 
       
  1946 lemma [intro]: "primerec rec_power (Suc (Suc 0))"
       
  1947 apply(simp add: rec_power_def  numeral_2_eq_2 numeral_3_eq_3)
       
  1948 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  1949     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  1950 done
       
  1951 
       
  1952 text {*
       
  1953   @{text "rec_lo"} is the recursive function used to implement @{text "Lo"}.
       
  1954 *}
       
  1955 definition rec_lo :: "recf"
       
  1956   where
       
  1957   "rec_lo = (let rR = Cn 3 rec_eq [Cn 3 rec_mod [id 3 0, 
       
  1958                Cn 3 rec_power [id 3 1, id 3 2]], 
       
  1959                      Cn 3 (constn 0) [id 3 1]] in
       
  1960              let rb =  Cn 2 (rec_maxr rR) [id 2 0, id 2 1, id 2 0] in 
       
  1961              let rcond = Cn 2 rec_conj [Cn 2 rec_less [Cn 2 (constn 1)
       
  1962                                              [id 2 0], id 2 0], 
       
  1963                                         Cn 2 rec_less [Cn 2 (constn 1)
       
  1964                                                 [id 2 0], id 2 1]] in 
       
  1965              let rcond2 = Cn 2 rec_minus 
       
  1966                               [Cn 2 (constn 1) [id 2 0], rcond] 
       
  1967              in Cn 2 rec_add [Cn 2 rec_mult [rb, rcond], 
       
  1968                   Cn 2 rec_mult [Cn 2 (constn 0) [id 2 0], rcond2]])"
       
  1969 
       
  1970 lemma rec_lo_Maxr_lor:
       
  1971   "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow>  
       
  1972         rec_exec rec_lo [x, y] = Maxr loR [x, y] x"
       
  1973 proof(auto simp: rec_exec.simps rec_lo_def Let_def 
       
  1974     numeral_2_eq_2 numeral_3_eq_3)
       
  1975   let ?rR = "(Cn (Suc (Suc (Suc 0))) rec_eq
       
  1976      [Cn (Suc (Suc (Suc 0))) rec_mod [recf.id (Suc (Suc (Suc 0))) 0,
       
  1977      Cn (Suc (Suc (Suc 0))) rec_power [recf.id (Suc (Suc (Suc 0)))
       
  1978      (Suc 0), recf.id (Suc (Suc (Suc 0))) (Suc (Suc 0))]],
       
  1979      Cn (Suc (Suc (Suc 0))) (constn 0) [recf.id (Suc (Suc (Suc 0))) (Suc 0)]])"
       
  1980   have h: "rec_exec (rec_maxr ?rR) ([x, y] @ [x]) =
       
  1981     Maxr (\<lambda> args. 0 < rec_exec ?rR args) [x, y] x"
       
  1982     by(rule_tac Maxr_lemma, auto simp: rec_exec.simps
       
  1983       mod_lemma power_lemma, auto simp: numeral_2_eq_2 numeral_3_eq_3)
       
  1984   have "Maxr loR [x, y] x =  Maxr (\<lambda> args. 0 < rec_exec ?rR args) [x, y] x"
       
  1985     apply(simp add: rec_exec.simps mod_lemma power_lemma)
       
  1986     apply(simp add: Maxr.simps loR.simps)
       
  1987     done
       
  1988   from h and this show "rec_exec (rec_maxr ?rR) [x, y, x] = 
       
  1989     Maxr loR [x, y] x"
       
  1990     apply(simp)
       
  1991     done
       
  1992 qed
       
  1993 
       
  1994 lemma [simp]: "Max {ya. ya = 0 \<and> loR [0, y, ya]} = 0"
       
  1995 apply(rule_tac Max_eqI, auto simp: loR.simps)
       
  1996 done
       
  1997 
       
  1998 lemma [simp]: "Suc 0 < y \<Longrightarrow> Suc (Suc 0) < y * y"
       
  1999 apply(induct y, simp)
       
  2000 apply(case_tac y, simp, simp)
       
  2001 done
       
  2002 
       
  2003 lemma less_mult: "\<lbrakk>x > 0; y > Suc 0\<rbrakk> \<Longrightarrow> x < y * x"
       
  2004 apply(case_tac y, simp, simp)
       
  2005 done
       
  2006 
       
  2007 lemma x_less_exp: "\<lbrakk>y > Suc 0\<rbrakk> \<Longrightarrow> x < y^x"
       
  2008 apply(induct x, simp, simp)
       
  2009 apply(case_tac x, simp, auto)
       
  2010 apply(rule_tac y = "y* y^nat" in le_less_trans, simp)
       
  2011 apply(rule_tac less_mult, auto)
       
  2012 done
       
  2013 
       
  2014 lemma le_mult: "y \<noteq> (0::nat) \<Longrightarrow> x \<le> x * y"  
       
  2015   by(induct y, simp, simp)
       
  2016 
       
  2017 lemma uplimit_loR:  "\<lbrakk>Suc 0 < x; Suc 0 < y; loR [x, y, xa]\<rbrakk> \<Longrightarrow> 
       
  2018   xa \<le> x"
       
  2019 apply(simp add: loR.simps)
       
  2020 apply(rule_tac classical, auto)
       
  2021 apply(subgoal_tac "xa < y^xa")
       
  2022 apply(subgoal_tac "y^xa \<le> y^xa * q", simp)
       
  2023 apply(rule_tac le_mult, case_tac q, simp, simp)
       
  2024 apply(rule_tac x_less_exp, simp)
       
  2025 done
       
  2026 
       
  2027 lemma [simp]: "\<lbrakk>xa \<le> x; loR [x, y, xa]; Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow>
       
  2028   {u. loR [x, y, u]} = {ya. ya \<le> x \<and> loR [x, y, ya]}"
       
  2029 apply(rule_tac Collect_cong, auto)
       
  2030 apply(erule_tac uplimit_loR, simp, simp)
       
  2031 done
       
  2032 
       
  2033 lemma Maxr_lo: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow>
       
  2034   Maxr loR [x, y] x = lo x y" 
       
  2035 apply(simp add: Maxr.simps lo.simps, auto)
       
  2036 apply(erule_tac x = xa in allE, simp, simp add: uplimit_loR)
       
  2037 done
       
  2038 
       
  2039 lemma lo_lemma': "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> 
       
  2040   rec_exec rec_lo [x, y] = lo x y"
       
  2041 by(simp add: Maxr_lo  rec_lo_Maxr_lor)
       
  2042 
       
  2043 lemma lo_lemma'': "\<lbrakk>\<not> Suc 0 < x\<rbrakk> \<Longrightarrow> rec_exec rec_lo [x, y] = lo x y"
       
  2044 apply(case_tac x, auto simp: rec_exec.simps rec_lo_def 
       
  2045   Let_def lo.simps)
       
  2046 done
       
  2047   
       
  2048 lemma lo_lemma''': "\<lbrakk>\<not> Suc 0 < y\<rbrakk> \<Longrightarrow> rec_exec rec_lo [x, y] = lo x y"
       
  2049 apply(case_tac y, auto simp: rec_exec.simps rec_lo_def 
       
  2050   Let_def lo.simps)
       
  2051 done
       
  2052 
       
  2053 text {*
       
  2054   The correctness of @{text "rec_lo"}:
       
  2055 *}
       
  2056 lemma lo_lemma: "rec_exec rec_lo [x, y] = lo x y" 
       
  2057 apply(case_tac "Suc 0 < x \<and> Suc 0 < y")
       
  2058 apply(auto simp: lo_lemma' lo_lemma'' lo_lemma''')
       
  2059 done
       
  2060 
       
  2061 fun lgR :: "nat list \<Rightarrow> bool"
       
  2062   where
       
  2063   "lgR [x, y, u] = (y^u \<le> x)"
       
  2064 
       
  2065 text {*
       
  2066   @{text "lg"} specifies the @{text "lg"} function given on page 79 of 
       
  2067   Boolos's book. It is one of the two notions of integeral logarithmatic
       
  2068   operation on that page. The other is @{text "lo"}.
       
  2069   *}
       
  2070 fun lg :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2071   where
       
  2072   "lg x y = (if x > 1 \<and> y > 1 \<and> {u. lgR [x, y, u]} \<noteq> {} then 
       
  2073                  Max {u. lgR [x, y, u]}
       
  2074               else 0)"
       
  2075 
       
  2076 declare lg.simps[simp del] lgR.simps[simp del]
       
  2077 
       
  2078 text {*
       
  2079   @{text "rec_lg"} is the recursive function used to implement @{text "lg"}.
       
  2080   *}
       
  2081 definition rec_lg :: "recf"
       
  2082   where
       
  2083   "rec_lg = (let rec_lgR = Cn 3 rec_le
       
  2084   [Cn 3 rec_power [id 3 1, id 3 2], id 3 0] in
       
  2085   let conR1 = Cn 2 rec_conj [Cn 2 rec_less 
       
  2086                      [Cn 2 (constn 1) [id 2 0], id 2 0], 
       
  2087                             Cn 2 rec_less [Cn 2 (constn 1) 
       
  2088                                  [id 2 0], id 2 1]] in 
       
  2089   let conR2 = Cn 2 rec_not [conR1] in 
       
  2090         Cn 2 rec_add [Cn 2 rec_mult 
       
  2091               [conR1, Cn 2 (rec_maxr rec_lgR)
       
  2092                        [id 2 0, id 2 1, id 2 0]], 
       
  2093                        Cn 2 rec_mult [conR2, Cn 2 (constn 0) 
       
  2094                                 [id 2 0]]])"
       
  2095 
       
  2096 lemma lg_maxr: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> 
       
  2097                       rec_exec rec_lg [x, y] = Maxr lgR [x, y] x"
       
  2098 proof(simp add: rec_exec.simps rec_lg_def Let_def)
       
  2099   assume h: "Suc 0 < x" "Suc 0 < y"
       
  2100   let ?rR = "(Cn 3 rec_le [Cn 3 rec_power
       
  2101                [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0])"
       
  2102   have "rec_exec (rec_maxr ?rR) ([x, y] @ [x])
       
  2103               = Maxr ((\<lambda> args. 0 < rec_exec ?rR args)) [x, y] x" 
       
  2104   proof(rule Maxr_lemma)
       
  2105     show "primerec (Cn 3 rec_le [Cn 3 rec_power 
       
  2106               [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0]) (Suc (length [x, y]))"
       
  2107       apply(auto simp: numeral_3_eq_3)+
       
  2108       done
       
  2109   qed
       
  2110   moreover have "Maxr lgR [x, y] x = Maxr ((\<lambda> args. 0 < rec_exec ?rR args)) [x, y] x"
       
  2111     apply(simp add: rec_exec.simps power_lemma)
       
  2112     apply(simp add: Maxr.simps lgR.simps)
       
  2113     done 
       
  2114   ultimately show "rec_exec (rec_maxr ?rR) [x, y, x] = Maxr lgR [x, y] x"
       
  2115     by simp
       
  2116 qed
       
  2117 
       
  2118 lemma [simp]: "\<lbrakk>Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow> xa \<le> x"
       
  2119 apply(simp add: lgR.simps)
       
  2120 apply(subgoal_tac "y^xa > xa", simp)
       
  2121 apply(erule x_less_exp)
       
  2122 done
       
  2123 
       
  2124 lemma [simp]: "\<lbrakk>Suc 0 < x; Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow>
       
  2125            {u. lgR [x, y, u]} =  {ya. ya \<le> x \<and> lgR [x, y, ya]}"
       
  2126 apply(rule_tac Collect_cong, auto)
       
  2127 done
       
  2128 
       
  2129 lemma maxr_lg: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> Maxr lgR [x, y] x = lg x y"
       
  2130 apply(simp add: lg.simps Maxr.simps, auto)
       
  2131 apply(erule_tac x = xa in allE, simp)
       
  2132 done
       
  2133 
       
  2134 lemma lg_lemma': "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y"
       
  2135 apply(simp add: maxr_lg lg_maxr)
       
  2136 done
       
  2137 
       
  2138 lemma lg_lemma'': "\<not> Suc 0 < x \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y"
       
  2139 apply(simp add: rec_exec.simps rec_lg_def Let_def lg.simps)
       
  2140 done
       
  2141 
       
  2142 lemma lg_lemma''': "\<not> Suc 0 < y \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y"
       
  2143 apply(simp add: rec_exec.simps rec_lg_def Let_def lg.simps)
       
  2144 done
       
  2145 
       
  2146 text {*
       
  2147   The correctness of @{text "rec_lg"}.
       
  2148   *}
       
  2149 lemma lg_lemma: "rec_exec rec_lg [x, y] = lg x y"
       
  2150 apply(case_tac "Suc 0 < x \<and> Suc 0 < y", auto simp: 
       
  2151                             lg_lemma' lg_lemma'' lg_lemma''')
       
  2152 done
       
  2153 
       
  2154 text {*
       
  2155   @{text "Entry sr i"} returns the @{text "i"}-th entry of a list of natural 
       
  2156   numbers encoded by number @{text "sr"} using Godel's coding.
       
  2157   *}
       
  2158 fun Entry :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2159   where
       
  2160   "Entry sr i = lo sr (Pi (Suc i))"
       
  2161 
       
  2162 text {*
       
  2163   @{text "rec_entry"} is the recursive function used to implement
       
  2164   @{text "Entry"}.
       
  2165   *}
       
  2166 definition rec_entry:: "recf"
       
  2167   where
       
  2168   "rec_entry = Cn 2 rec_lo [id 2 0, Cn 2 rec_pi [Cn 2 s [id 2 1]]]"
       
  2169 
       
  2170 declare Pi.simps[simp del]
       
  2171 
       
  2172 text {*
       
  2173   The correctness of @{text "rec_entry"}.
       
  2174   *}
       
  2175 lemma entry_lemma: "rec_exec rec_entry [str, i] = Entry str i"
       
  2176   by(simp add: rec_entry_def  rec_exec.simps lo_lemma pi_lemma)
       
  2177 
       
  2178 section {* The construction of @{text "F"} *}
       
  2179 
       
  2180 text {*
       
  2181   Using the auxilliary functions obtained in last section, 
       
  2182   we are going to contruct the function @{text "F"}, 
       
  2183   which is an interpreter of Turing Machines.
       
  2184   *}
       
  2185 
       
  2186 fun listsum2 :: "nat list \<Rightarrow> nat \<Rightarrow> nat"
       
  2187   where
       
  2188   "listsum2 xs 0 = 0"
       
  2189 | "listsum2 xs (Suc n) = listsum2 xs n + xs ! n"
       
  2190 
       
  2191 fun rec_listsum2 :: "nat \<Rightarrow> nat \<Rightarrow> recf"
       
  2192   where
       
  2193   "rec_listsum2 vl 0 = Cn vl z [id vl 0]"
       
  2194 | "rec_listsum2 vl (Suc n) = Cn vl rec_add 
       
  2195                       [rec_listsum2 vl n, id vl (n)]"
       
  2196 
       
  2197 declare listsum2.simps[simp del] rec_listsum2.simps[simp del]
       
  2198 
       
  2199 lemma listsum2_lemma: "\<lbrakk>length xs = vl; n \<le> vl\<rbrakk> \<Longrightarrow> 
       
  2200       rec_exec (rec_listsum2 vl n) xs = listsum2 xs n"
       
  2201 apply(induct n, simp_all)
       
  2202 apply(simp_all add: rec_exec.simps rec_listsum2.simps listsum2.simps)
       
  2203 done
       
  2204 
       
  2205 fun strt' :: "nat list \<Rightarrow> nat \<Rightarrow> nat"
       
  2206   where
       
  2207   "strt' xs 0 = 0"
       
  2208 | "strt' xs (Suc n) = (let dbound = listsum2 xs n + n in 
       
  2209                        strt' xs n + (2^(xs ! n + dbound) - 2^dbound))"
       
  2210 
       
  2211 fun rec_strt' :: "nat \<Rightarrow> nat \<Rightarrow> recf"
       
  2212   where
       
  2213   "rec_strt' vl 0 = Cn vl z [id vl 0]"
       
  2214 | "rec_strt' vl (Suc n) = (let rec_dbound =
       
  2215   Cn vl rec_add [rec_listsum2 vl n, Cn vl (constn n) [id vl 0]]
       
  2216   in Cn vl rec_add [rec_strt' vl n, Cn vl rec_minus 
       
  2217   [Cn vl rec_power [Cn vl (constn 2) [id vl 0], Cn vl rec_add
       
  2218   [id vl (n), rec_dbound]], 
       
  2219   Cn vl rec_power [Cn vl (constn 2) [id vl 0], rec_dbound]]])"
       
  2220 
       
  2221 declare strt'.simps[simp del] rec_strt'.simps[simp del]
       
  2222 
       
  2223 lemma strt'_lemma: "\<lbrakk>length xs = vl; n \<le> vl\<rbrakk> \<Longrightarrow> 
       
  2224   rec_exec (rec_strt' vl n) xs = strt' xs n"
       
  2225 apply(induct n)
       
  2226 apply(simp_all add: rec_exec.simps rec_strt'.simps strt'.simps
       
  2227   Let_def power_lemma listsum2_lemma)
       
  2228 done
       
  2229 
       
  2230 text {*
       
  2231   @{text "strt"} corresponds to the @{text "strt"} function on page 90 of B book, but 
       
  2232   this definition generalises the original one to deal with multiple input arguments.
       
  2233   *}
       
  2234 fun strt :: "nat list \<Rightarrow> nat"
       
  2235   where
       
  2236   "strt xs = (let ys = map Suc xs in 
       
  2237               strt' ys (length ys))"
       
  2238 
       
  2239 fun rec_map :: "recf \<Rightarrow> nat \<Rightarrow> recf list"
       
  2240   where
       
  2241   "rec_map rf vl = map (\<lambda> i. Cn vl rf [id vl (i)]) [0..<vl]"
       
  2242 
       
  2243 text {*
       
  2244   @{text "rec_strt"} is the recursive function used to implement @{text "strt"}.
       
  2245   *}
       
  2246 fun rec_strt :: "nat \<Rightarrow> recf"
       
  2247   where
       
  2248   "rec_strt vl = Cn vl (rec_strt' vl vl) (rec_map s vl)"
       
  2249 
       
  2250 lemma map_s_lemma: "length xs = vl \<Longrightarrow> 
       
  2251   map ((\<lambda>a. rec_exec a xs) \<circ> (\<lambda>i. Cn vl s [recf.id vl i]))
       
  2252   [0..<vl]
       
  2253         = map Suc xs"
       
  2254 apply(induct vl arbitrary: xs, simp, auto simp: rec_exec.simps)
       
  2255 apply(subgoal_tac "\<exists> ys y. xs = ys @ [y]", auto)
       
  2256 proof -
       
  2257   fix ys y
       
  2258   assume ind: "\<And>xs. length xs = length (ys::nat list) \<Longrightarrow>
       
  2259       map ((\<lambda>a. rec_exec a xs) \<circ> (\<lambda>i. Cn (length ys) s 
       
  2260         [recf.id (length ys) (i)])) [0..<length ys] = map Suc xs"
       
  2261   show
       
  2262     "map ((\<lambda>a. rec_exec a (ys @ [y])) \<circ> (\<lambda>i. Cn (Suc (length ys)) s 
       
  2263   [recf.id (Suc (length ys)) (i)])) [0..<length ys] = map Suc ys"
       
  2264   proof -
       
  2265     have "map ((\<lambda>a. rec_exec a ys) \<circ> (\<lambda>i. Cn (length ys) s
       
  2266         [recf.id (length ys) (i)])) [0..<length ys] = map Suc ys"
       
  2267       apply(rule_tac ind, simp)
       
  2268       done
       
  2269     moreover have
       
  2270       "map ((\<lambda>a. rec_exec a (ys @ [y])) \<circ> (\<lambda>i. Cn (Suc (length ys)) s
       
  2271            [recf.id (Suc (length ys)) (i)])) [0..<length ys]
       
  2272          = map ((\<lambda>a. rec_exec a ys) \<circ> (\<lambda>i. Cn (length ys) s 
       
  2273                  [recf.id (length ys) (i)])) [0..<length ys]"
       
  2274       apply(rule_tac map_ext, auto simp: rec_exec.simps nth_append)
       
  2275       done
       
  2276     ultimately show "?thesis"
       
  2277       by simp
       
  2278   qed
       
  2279 next
       
  2280   fix vl xs
       
  2281   assume "length xs = Suc vl"
       
  2282   thus "\<exists>ys y. xs = ys @ [y]"
       
  2283     apply(rule_tac x = "butlast xs" in exI, rule_tac x = "last xs" in exI)
       
  2284     apply(subgoal_tac "xs \<noteq> []", auto)
       
  2285     done
       
  2286 qed
       
  2287 
       
  2288 text {*
       
  2289   The correctness of @{text "rec_strt"}.
       
  2290   *}
       
  2291 lemma strt_lemma: "length xs = vl \<Longrightarrow> 
       
  2292   rec_exec (rec_strt vl) xs = strt xs"
       
  2293 apply(simp add: strt.simps rec_exec.simps strt'_lemma)
       
  2294 apply(subgoal_tac "(map ((\<lambda>a. rec_exec a xs) \<circ> (\<lambda>i. Cn vl s [recf.id vl (i)])) [0..<vl])
       
  2295                   = map Suc xs", auto)
       
  2296 apply(rule map_s_lemma, simp)
       
  2297 done
       
  2298 
       
  2299 text {*
       
  2300   The @{text "scan"} function on page 90 of B book.
       
  2301   *}
       
  2302 fun scan :: "nat \<Rightarrow> nat"
       
  2303   where
       
  2304   "scan r = r mod 2"
       
  2305 
       
  2306 text {*
       
  2307   @{text "rec_scan"} is the implemention of @{text "scan"}.
       
  2308   *}
       
  2309 definition rec_scan :: "recf"
       
  2310   where "rec_scan = Cn 1 rec_mod [id 1 0, constn 2]"
       
  2311 
       
  2312 text {*
       
  2313   The correctness of @{text "scan"}.
       
  2314   *}
       
  2315 lemma scan_lemma: "rec_exec rec_scan [r] = r mod 2"
       
  2316   by(simp add: rec_exec.simps rec_scan_def mod_lemma)
       
  2317 
       
  2318 fun newleft0 :: "nat list \<Rightarrow> nat"
       
  2319   where
       
  2320   "newleft0 [p, r] = p"
       
  2321 
       
  2322 definition rec_newleft0 :: "recf"
       
  2323   where
       
  2324   "rec_newleft0 = id 2 0"
       
  2325 
       
  2326 fun newrgt0 :: "nat list \<Rightarrow> nat"
       
  2327   where
       
  2328   "newrgt0 [p, r] = r - scan r"
       
  2329 
       
  2330 definition rec_newrgt0 :: "recf"
       
  2331   where
       
  2332   "rec_newrgt0 = Cn 2 rec_minus [id 2 1, Cn 2 rec_scan [id 2 1]]"
       
  2333 
       
  2334 (*newleft1, newrgt1: left rgt number after execute on step*)
       
  2335 fun newleft1 :: "nat list \<Rightarrow> nat"
       
  2336   where
       
  2337   "newleft1 [p, r] = p"
       
  2338 
       
  2339 definition rec_newleft1 :: "recf"
       
  2340   where
       
  2341   "rec_newleft1 = id 2 0"
       
  2342 
       
  2343 fun newrgt1 :: "nat list \<Rightarrow> nat"
       
  2344   where
       
  2345   "newrgt1 [p, r] = r + 1 - scan r"
       
  2346 
       
  2347 definition rec_newrgt1 :: "recf"
       
  2348   where
       
  2349   "rec_newrgt1 = 
       
  2350   Cn 2 rec_minus [Cn 2 rec_add [id 2 1, Cn 2 (constn 1) [id 2 0]], 
       
  2351                   Cn 2 rec_scan [id 2 1]]"
       
  2352 
       
  2353 fun newleft2 :: "nat list \<Rightarrow> nat"
       
  2354   where
       
  2355   "newleft2 [p, r] = p div 2"
       
  2356 
       
  2357 definition rec_newleft2 :: "recf" 
       
  2358   where
       
  2359   "rec_newleft2 = Cn 2 rec_quo [id 2 0, Cn 2 (constn 2) [id 2 0]]"
       
  2360 
       
  2361 fun newrgt2 :: "nat list \<Rightarrow> nat"
       
  2362   where
       
  2363   "newrgt2 [p, r] = 2 * r + p mod 2"
       
  2364 
       
  2365 definition rec_newrgt2 :: "recf"
       
  2366   where
       
  2367   "rec_newrgt2 =
       
  2368     Cn 2 rec_add [Cn 2 rec_mult [Cn 2 (constn 2) [id 2 0], id 2 1],                     
       
  2369                  Cn 2 rec_mod [id 2 0, Cn 2 (constn 2) [id 2 0]]]"
       
  2370 
       
  2371 fun newleft3 :: "nat list \<Rightarrow> nat"
       
  2372   where
       
  2373   "newleft3 [p, r] = 2 * p + r mod 2"
       
  2374 
       
  2375 definition rec_newleft3 :: "recf"
       
  2376   where
       
  2377   "rec_newleft3 = 
       
  2378   Cn 2 rec_add [Cn 2 rec_mult [Cn 2 (constn 2) [id 2 0], id 2 0], 
       
  2379                 Cn 2 rec_mod [id 2 1, Cn 2 (constn 2) [id 2 0]]]"
       
  2380 
       
  2381 fun newrgt3 :: "nat list \<Rightarrow> nat"
       
  2382   where
       
  2383   "newrgt3 [p, r] = r div 2"
       
  2384 
       
  2385 definition rec_newrgt3 :: "recf"
       
  2386   where
       
  2387   "rec_newrgt3 = Cn 2 rec_quo [id 2 1, Cn 2 (constn 2) [id 2 0]]"
       
  2388 
       
  2389 text {*
       
  2390   The @{text "new_left"} function on page 91 of B book.
       
  2391   *}
       
  2392 fun newleft :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2393   where
       
  2394   "newleft p r a = (if a = 0 \<or> a = 1 then newleft0 [p, r] 
       
  2395                     else if a = 2 then newleft2 [p, r]
       
  2396                     else if a = 3 then newleft3 [p, r]
       
  2397                     else p)"
       
  2398 
       
  2399 text {*
       
  2400   @{text "rec_newleft"} is the recursive function used to 
       
  2401   implement @{text "newleft"}.
       
  2402   *}
       
  2403 definition rec_newleft :: "recf" 
       
  2404   where
       
  2405   "rec_newleft =
       
  2406   (let g0 = 
       
  2407       Cn 3 rec_newleft0 [id 3 0, id 3 1] in 
       
  2408   let g1 = Cn 3 rec_newleft2 [id 3 0, id 3 1] in 
       
  2409   let g2 = Cn 3 rec_newleft3 [id 3 0, id 3 1] in 
       
  2410   let g3 = id 3 0 in
       
  2411   let r0 = Cn 3 rec_disj
       
  2412           [Cn 3 rec_eq [id 3 2, Cn 3 (constn 0) [id 3 0]],
       
  2413            Cn 3 rec_eq [id 3 2, Cn 3 (constn 1) [id 3 0]]] in 
       
  2414   let r1 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 2) [id 3 0]] in 
       
  2415   let r2 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 3) [id 3 0]] in
       
  2416   let r3 = Cn 3 rec_less [Cn 3 (constn 3) [id 3 0], id 3 2] in 
       
  2417   let gs = [g0, g1, g2, g3] in 
       
  2418   let rs = [r0, r1, r2, r3] in 
       
  2419   rec_embranch (zip gs rs))"
       
  2420 
       
  2421 declare newleft.simps[simp del]
       
  2422 
       
  2423 
       
  2424 lemma Suc_Suc_Suc_Suc_induct: 
       
  2425   "\<lbrakk>i < Suc (Suc (Suc (Suc 0))); i = 0 \<Longrightarrow>  P i;
       
  2426     i = 1 \<Longrightarrow> P i; i =2 \<Longrightarrow> P i; 
       
  2427     i =3 \<Longrightarrow> P i\<rbrakk> \<Longrightarrow> P i"
       
  2428 apply(case_tac i, simp, case_tac nat, simp, 
       
  2429       case_tac nata, simp, case_tac natb, simp, simp)
       
  2430 done
       
  2431 
       
  2432 declare quo_lemma2[simp] mod_lemma[simp]
       
  2433 
       
  2434 text {*
       
  2435   The correctness of @{text "rec_newleft"}.
       
  2436   *}
       
  2437 lemma newleft_lemma: 
       
  2438   "rec_exec rec_newleft [p, r, a] = newleft p r a"
       
  2439 proof(simp only: rec_newleft_def Let_def)
       
  2440   let ?rgs = "[Cn 3 rec_newleft0 [recf.id 3 0, recf.id 3 1], Cn 3 rec_newleft2 
       
  2441        [recf.id 3 0, recf.id 3 1], Cn 3 rec_newleft3 [recf.id 3 0, recf.id 3 1], recf.id 3 0]"
       
  2442   let ?rrs = 
       
  2443     "[Cn 3 rec_disj [Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 0) 
       
  2444      [recf.id 3 0]], Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 1) [recf.id 3 0]]], 
       
  2445      Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 2) [recf.id 3 0]],
       
  2446      Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 3) [recf.id 3 0]],
       
  2447      Cn 3 rec_less [Cn 3 (constn 3) [recf.id 3 0], recf.id 3 2]]"
       
  2448   thm embranch_lemma
       
  2449   have k1: "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a]
       
  2450                          = Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a]"
       
  2451     apply(rule_tac embranch_lemma )
       
  2452     apply(auto simp: numeral_3_eq_3 numeral_2_eq_2 rec_newleft0_def 
       
  2453              rec_newleft1_def rec_newleft2_def rec_newleft3_def)+
       
  2454     apply(case_tac "a = 0 \<or> a = 1", rule_tac x = 0 in exI)
       
  2455     prefer 2
       
  2456     apply(case_tac "a = 2", rule_tac x = "Suc 0" in exI)
       
  2457     prefer 2
       
  2458     apply(case_tac "a = 3", rule_tac x = "2" in exI)
       
  2459     prefer 2
       
  2460     apply(case_tac "a > 3", rule_tac x = "3" in exI, auto)
       
  2461     apply(auto simp: rec_exec.simps)
       
  2462     apply(erule_tac [!] Suc_Suc_Suc_Suc_induct, auto simp: rec_exec.simps)
       
  2463     done(*
       
  2464   have "Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a]
       
  2465       = Embranch (zip ?gs ?rs) [p, r, a]"
       
  2466     apply(simp add)*)
       
  2467   have k2: "Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a] = newleft p r a"
       
  2468     apply(simp add: Embranch.simps)
       
  2469     apply(simp add: rec_exec.simps)
       
  2470     apply(auto simp: newleft.simps rec_newleft0_def rec_exec.simps
       
  2471                      rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  2472     done
       
  2473   from k1 and k2 show 
       
  2474    "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a] = newleft p r a"
       
  2475     by simp
       
  2476 qed
       
  2477 
       
  2478 text {* 
       
  2479   The @{text "newrght"} function is one similar to @{text "newleft"}, but used to 
       
  2480   compute the right number.
       
  2481   *}
       
  2482 fun newrght :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2483   where
       
  2484   "newrght p r a  = (if a = 0 then newrgt0 [p, r]
       
  2485                     else if a = 1 then newrgt1 [p, r]
       
  2486                     else if a = 2 then newrgt2 [p, r]
       
  2487                     else if a = 3 then newrgt3 [p, r]
       
  2488                     else r)"
       
  2489 
       
  2490 text {*
       
  2491   @{text "rec_newrght"} is the recursive function used to implement 
       
  2492   @{text "newrgth"}.
       
  2493   *}
       
  2494 definition rec_newrght :: "recf" 
       
  2495   where
       
  2496   "rec_newrght =
       
  2497   (let g0 = Cn 3 rec_newrgt0 [id 3 0, id 3 1] in 
       
  2498   let g1 = Cn 3 rec_newrgt1 [id 3 0, id 3 1] in 
       
  2499   let g2 = Cn 3 rec_newrgt2 [id 3 0, id 3 1] in 
       
  2500   let g3 = Cn 3 rec_newrgt3 [id 3 0, id 3 1] in
       
  2501   let g4 = id 3 1 in 
       
  2502   let r0 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 0) [id 3 0]] in 
       
  2503   let r1 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 1) [id 3 0]] in 
       
  2504   let r2 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 2) [id 3 0]] in
       
  2505   let r3 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 3) [id 3 0]] in
       
  2506   let r4 = Cn 3 rec_less [Cn 3 (constn 3) [id 3 0], id 3 2] in 
       
  2507   let gs = [g0, g1, g2, g3, g4] in 
       
  2508   let rs = [r0, r1, r2, r3, r4] in 
       
  2509   rec_embranch (zip gs rs))"
       
  2510 declare newrght.simps[simp del]
       
  2511 
       
  2512 lemma numeral_4_eq_4: "4 = Suc 3"
       
  2513 by auto
       
  2514 
       
  2515 lemma Suc_5_induct: 
       
  2516   "\<lbrakk>i < Suc (Suc (Suc (Suc (Suc 0)))); i = 0 \<Longrightarrow> P 0;
       
  2517   i = 1 \<Longrightarrow> P 1; i = 2 \<Longrightarrow> P 2; i = 3 \<Longrightarrow> P 3; i = 4 \<Longrightarrow> P 4\<rbrakk> \<Longrightarrow> P i"
       
  2518 apply(case_tac i, auto)
       
  2519 apply(case_tac nat, auto)
       
  2520 apply(case_tac nata, auto simp: numeral_2_eq_2)
       
  2521 apply(case_tac nat, auto simp: numeral_3_eq_3 numeral_4_eq_4)
       
  2522 done
       
  2523 
       
  2524 lemma [intro]: "primerec rec_scan (Suc 0)"
       
  2525 apply(auto simp: rec_scan_def, auto)
       
  2526 done
       
  2527 
       
  2528 text {*
       
  2529   The correctness of @{text "rec_newrght"}.
       
  2530   *}
       
  2531 lemma newrght_lemma: "rec_exec rec_newrght [p, r, a] = newrght p r a"
       
  2532 proof(simp only: rec_newrght_def Let_def)
       
  2533   let ?gs' = "[newrgt0, newrgt1, newrgt2, newrgt3, \<lambda> zs. zs ! 1]"
       
  2534   let ?r0 = "\<lambda> zs. zs ! 2 = 0"
       
  2535   let ?r1 = "\<lambda> zs. zs ! 2 = 1"
       
  2536   let ?r2 = "\<lambda> zs. zs ! 2 = 2"
       
  2537   let ?r3 = "\<lambda> zs. zs ! 2 = 3"
       
  2538   let ?r4 = "\<lambda> zs. zs ! 2 > 3"
       
  2539   let ?gs = "map (\<lambda> g. (\<lambda> zs. g [zs ! 0, zs ! 1])) ?gs'"
       
  2540   let ?rs = "[?r0, ?r1, ?r2, ?r3, ?r4]"
       
  2541   let ?rgs = 
       
  2542  "[Cn 3 rec_newrgt0 [recf.id 3 0, recf.id 3 1],
       
  2543     Cn 3 rec_newrgt1 [recf.id 3 0, recf.id 3 1],
       
  2544      Cn 3 rec_newrgt2 [recf.id 3 0, recf.id 3 1], 
       
  2545       Cn 3 rec_newrgt3 [recf.id 3 0, recf.id 3 1], recf.id 3 1]"
       
  2546   let ?rrs = 
       
  2547  "[Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 0) [recf.id 3 0]], Cn 3 rec_eq [recf.id 3 2, 
       
  2548     Cn 3 (constn 1) [recf.id 3 0]], Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 2) [recf.id 3 0]],
       
  2549      Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 3) [recf.id 3 0]], 
       
  2550        Cn 3 rec_less [Cn 3 (constn 3) [recf.id 3 0], recf.id 3 2]]"
       
  2551     
       
  2552   have k1: "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a]
       
  2553     = Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a]"
       
  2554     apply(rule_tac embranch_lemma)
       
  2555     apply(auto simp: numeral_3_eq_3 numeral_2_eq_2 rec_newrgt0_def 
       
  2556              rec_newrgt1_def rec_newrgt2_def rec_newrgt3_def)+
       
  2557     apply(case_tac "a = 0", rule_tac x = 0 in exI)
       
  2558     prefer 2
       
  2559     apply(case_tac "a = 1", rule_tac x = "Suc 0" in exI)
       
  2560     prefer 2
       
  2561     apply(case_tac "a = 2", rule_tac x = "2" in exI)
       
  2562     prefer 2
       
  2563     apply(case_tac "a = 3", rule_tac x = "3" in exI)
       
  2564     prefer 2
       
  2565     apply(case_tac "a > 3", rule_tac x = "4" in exI, auto simp: rec_exec.simps)
       
  2566     apply(erule_tac [!] Suc_5_induct, auto simp: rec_exec.simps)
       
  2567     done
       
  2568   have k2: "Embranch (zip (map rec_exec ?rgs)
       
  2569     (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a] = newrght p r a"
       
  2570     apply(auto simp:Embranch.simps rec_exec.simps)
       
  2571     apply(auto simp: newrght.simps rec_newrgt3_def rec_newrgt2_def
       
  2572                      rec_newrgt1_def rec_newrgt0_def rec_exec.simps
       
  2573                      scan_lemma)
       
  2574     done
       
  2575   from k1 and k2 show 
       
  2576     "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a] =      
       
  2577                                     newrght p r a" by simp
       
  2578 qed
       
  2579 
       
  2580 declare Entry.simps[simp del]
       
  2581 
       
  2582 text {*
       
  2583   The @{text "actn"} function given on page 92 of B book, which is used to 
       
  2584   fetch Turing Machine intructions. 
       
  2585   In @{text "actn m q r"}, @{text "m"} is the Godel coding of a Turing Machine,
       
  2586   @{text "q"} is the current state of Turing Machine, @{text "r"} is the
       
  2587   right number of Turing Machine tape.
       
  2588   *}
       
  2589 fun actn :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2590   where
       
  2591   "actn m q r = (if q \<noteq> 0 then Entry m (4*(q - 1) + 2 * scan r)
       
  2592                  else 4)"
       
  2593 
       
  2594 text {*
       
  2595   @{text "rec_actn"} is the recursive function used to implement @{text "actn"}
       
  2596   *}
       
  2597 definition rec_actn :: "recf"
       
  2598   where
       
  2599   "rec_actn = 
       
  2600   Cn 3 rec_add [Cn 3 rec_mult 
       
  2601         [Cn 3 rec_entry [id 3 0, Cn 3 rec_add [Cn 3 rec_mult 
       
  2602                                  [Cn 3 (constn 4) [id 3 0], 
       
  2603                 Cn 3 rec_minus [id 3 1, Cn 3 (constn 1) [id 3 0]]], 
       
  2604                    Cn 3 rec_mult [Cn 3 (constn 2) [id 3 0],
       
  2605                       Cn 3 rec_scan [id 3 2]]]], 
       
  2606             Cn 3 rec_noteq [id 3 1, Cn 3 (constn 0) [id 3 0]]], 
       
  2607                              Cn 3 rec_mult [Cn 3 (constn 4) [id 3 0], 
       
  2608              Cn 3 rec_eq [id 3 1, Cn 3 (constn 0) [id 3 0]]]] "
       
  2609 
       
  2610 text {*
       
  2611   The correctness of @{text "actn"}.
       
  2612   *}
       
  2613 lemma actn_lemma: "rec_exec rec_actn [m, q, r] = actn m q r"
       
  2614   by(auto simp: rec_actn_def rec_exec.simps entry_lemma scan_lemma)
       
  2615 
       
  2616 (* Stop point *)
       
  2617 
       
  2618 fun newstat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2619   where
       
  2620   "newstat m q r = (if q \<noteq> 0 then Entry m (4*(q - 1) + 2*scan r + 1)
       
  2621                     else 0)"
       
  2622 
       
  2623 definition rec_newstat :: "recf"
       
  2624   where
       
  2625   "rec_newstat = Cn 3 rec_add 
       
  2626     [Cn 3 rec_mult [Cn 3 rec_entry [id 3 0, 
       
  2627            Cn 3 rec_add [Cn 3 rec_mult [Cn 3 (constn 4) [id 3 0], 
       
  2628            Cn 3 rec_minus [id 3 1, Cn 3 (constn 1) [id 3 0]]], 
       
  2629            Cn 3 rec_add [Cn 3 rec_mult [Cn 3 (constn 2) [id 3 0],
       
  2630            Cn 3 rec_scan [id 3 2]], Cn 3 (constn 1) [id 3 0]]]], 
       
  2631            Cn 3 rec_noteq [id 3 1, Cn 3 (constn 0) [id 3 0]]], 
       
  2632            Cn 3 rec_mult [Cn 3 (constn 0) [id 3 0], 
       
  2633            Cn 3 rec_eq [id 3 1, Cn 3 (constn 0) [id 3 0]]]] "
       
  2634 
       
  2635 lemma newstat_lemma: "rec_exec rec_newstat [m, q, r] = newstat m q r"
       
  2636 by(auto simp:  rec_exec.simps entry_lemma scan_lemma rec_newstat_def)
       
  2637 
       
  2638 declare newstat.simps[simp del] actn.simps[simp del]
       
  2639 
       
  2640 text{*code the configuration*}
       
  2641 
       
  2642 fun trpl :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2643   where
       
  2644   "trpl p q r = (Pi 0)^p * (Pi 1)^q * (Pi 2)^r"
       
  2645 
       
  2646 definition rec_trpl :: "recf"
       
  2647   where
       
  2648   "rec_trpl = Cn 3 rec_mult [Cn 3 rec_mult 
       
  2649        [Cn 3 rec_power [Cn 3 (constn (Pi 0)) [id 3 0], id 3 0], 
       
  2650         Cn 3 rec_power [Cn 3 (constn (Pi 1)) [id 3 0], id 3 1]],
       
  2651         Cn 3 rec_power [Cn 3 (constn (Pi 2)) [id 3 0], id 3 2]]"
       
  2652 declare trpl.simps[simp del]
       
  2653 lemma trpl_lemma: "rec_exec rec_trpl [p, q, r] = trpl p q r"
       
  2654 by(auto simp: rec_trpl_def rec_exec.simps power_lemma trpl.simps)
       
  2655 
       
  2656 text{*left, stat, rght: decode func*}
       
  2657 fun left :: "nat \<Rightarrow> nat"
       
  2658   where
       
  2659   "left c = lo c (Pi 0)"
       
  2660 
       
  2661 fun stat :: "nat \<Rightarrow> nat"
       
  2662   where
       
  2663   "stat c = lo c (Pi 1)"
       
  2664 
       
  2665 fun rght :: "nat \<Rightarrow> nat"
       
  2666   where
       
  2667   "rght c = lo c (Pi 2)"
       
  2668 
       
  2669 thm Prime.simps
       
  2670 
       
  2671 fun inpt :: "nat \<Rightarrow> nat list \<Rightarrow> nat"
       
  2672   where
       
  2673   "inpt m xs = trpl 0 1 (strt xs)"
       
  2674 
       
  2675 fun newconf :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2676   where
       
  2677   "newconf m c = trpl (newleft (left c) (rght c) 
       
  2678                         (actn m (stat c) (rght c)))
       
  2679                         (newstat m (stat c) (rght c)) 
       
  2680                         (newrght (left c) (rght c) 
       
  2681                               (actn m (stat c) (rght c)))"
       
  2682   
       
  2683 declare left.simps[simp del] stat.simps[simp del] rght.simps[simp del]
       
  2684         inpt.simps[simp del] newconf.simps[simp del]
       
  2685 
       
  2686 definition rec_left :: "recf"
       
  2687   where
       
  2688   "rec_left = Cn 1 rec_lo [id 1 0, constn (Pi 0)]"
       
  2689 
       
  2690 definition rec_right :: "recf"
       
  2691   where
       
  2692   "rec_right = Cn 1 rec_lo [id 1 0, constn (Pi 2)]"
       
  2693 
       
  2694 definition rec_stat :: "recf"
       
  2695   where
       
  2696   "rec_stat = Cn 1 rec_lo [id 1 0, constn (Pi 1)]"
       
  2697 
       
  2698 definition rec_inpt :: "nat \<Rightarrow> recf"
       
  2699   where
       
  2700   "rec_inpt vl = Cn vl rec_trpl 
       
  2701                   [Cn vl (constn 0) [id vl 0], 
       
  2702                    Cn vl (constn 1) [id vl 0], 
       
  2703                    Cn vl (rec_strt (vl - 1)) 
       
  2704                         (map (\<lambda> i. id vl (i)) [1..<vl])]"
       
  2705 
       
  2706 lemma left_lemma: "rec_exec rec_left [c] = left c"
       
  2707 by(simp add: rec_exec.simps rec_left_def left.simps lo_lemma)
       
  2708       
       
  2709 lemma right_lemma: "rec_exec rec_right [c] = rght c"
       
  2710 by(simp add: rec_exec.simps rec_right_def rght.simps lo_lemma)
       
  2711 
       
  2712 lemma stat_lemma: "rec_exec rec_stat [c] = stat c"
       
  2713 by(simp add: rec_exec.simps rec_stat_def stat.simps lo_lemma)
       
  2714  
       
  2715 declare rec_strt.simps[simp del] strt.simps[simp del]
       
  2716 
       
  2717 lemma map_cons_eq: 
       
  2718   "(map ((\<lambda>a. rec_exec a (m # xs)) \<circ> 
       
  2719     (\<lambda>i. recf.id (Suc (length xs)) (i))) 
       
  2720           [Suc 0..<Suc (length xs)])
       
  2721         = map (\<lambda> i. xs ! (i - 1)) [Suc 0..<Suc (length xs)]"
       
  2722 apply(rule map_ext, auto)
       
  2723 apply(auto simp: rec_exec.simps nth_append nth_Cons split: nat.split)
       
  2724 done
       
  2725 
       
  2726 lemma list_map_eq: 
       
  2727   "vl = length (xs::nat list) \<Longrightarrow> map (\<lambda> i. xs ! (i - 1))
       
  2728                                           [Suc 0..<Suc vl] = xs"
       
  2729 apply(induct vl arbitrary: xs, simp)
       
  2730 apply(subgoal_tac "\<exists> ys y. xs = ys @ [y]", auto)
       
  2731 proof -
       
  2732   fix ys y
       
  2733   assume ind: 
       
  2734     "\<And>xs. length (ys::nat list) = length (xs::nat list) \<Longrightarrow>
       
  2735             map (\<lambda>i. xs ! (i - Suc 0)) [Suc 0..<length xs] @
       
  2736                                 [xs ! (length xs - Suc 0)] = xs"
       
  2737   and h: "Suc 0 \<le> length (ys::nat list)"
       
  2738   have "map (\<lambda>i. ys ! (i - Suc 0)) [Suc 0..<length ys] @ 
       
  2739                                    [ys ! (length ys - Suc 0)] = ys"
       
  2740     apply(rule_tac ind, simp)
       
  2741     done
       
  2742   moreover have 
       
  2743     "map (\<lambda>i. (ys @ [y]) ! (i - Suc 0)) [Suc 0..<length ys]
       
  2744       = map (\<lambda>i. ys ! (i - Suc 0)) [Suc 0..<length ys]"
       
  2745     apply(rule map_ext)
       
  2746     using h
       
  2747     apply(auto simp: nth_append)
       
  2748     done
       
  2749   ultimately show "map (\<lambda>i. (ys @ [y]) ! (i - Suc 0)) 
       
  2750         [Suc 0..<length ys] @ [(ys @ [y]) ! (length ys - Suc 0)] = ys"
       
  2751     apply(simp del: map_eq_conv add: nth_append, auto)
       
  2752     using h
       
  2753     apply(simp)
       
  2754     done
       
  2755 next
       
  2756   fix vl xs
       
  2757   assume "Suc vl = length (xs::nat list)"
       
  2758   thus "\<exists>ys y. xs = ys @ [y]"
       
  2759     apply(rule_tac x = "butlast xs" in exI, 
       
  2760           rule_tac x = "last xs" in exI)
       
  2761     apply(case_tac "xs \<noteq> []", auto)
       
  2762     done
       
  2763 qed
       
  2764 
       
  2765 lemma [elim]: 
       
  2766   "Suc 0 \<le> length xs \<Longrightarrow> 
       
  2767      (map ((\<lambda>a. rec_exec a (m # xs)) \<circ> 
       
  2768          (\<lambda>i. recf.id (Suc (length xs)) (i))) 
       
  2769              [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs"
       
  2770 using map_cons_eq[of m xs]
       
  2771 apply(simp del: map_eq_conv add: rec_exec.simps)
       
  2772 using list_map_eq[of "length xs" xs]
       
  2773 apply(simp)
       
  2774 done
       
  2775 
       
  2776     
       
  2777 lemma inpt_lemma:
       
  2778   "\<lbrakk>Suc (length xs) = vl\<rbrakk> \<Longrightarrow> 
       
  2779             rec_exec (rec_inpt vl) (m # xs) = inpt m xs"
       
  2780 apply(auto simp: rec_exec.simps rec_inpt_def 
       
  2781                  trpl_lemma inpt.simps strt_lemma)
       
  2782 apply(subgoal_tac
       
  2783   "(map ((\<lambda>a. rec_exec a (m # xs)) \<circ> 
       
  2784           (\<lambda>i. recf.id (Suc (length xs)) (i))) 
       
  2785             [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs", simp)
       
  2786 apply(auto, case_tac xs, auto)
       
  2787 done
       
  2788 
       
  2789 definition rec_newconf:: "recf"
       
  2790   where
       
  2791   "rec_newconf = 
       
  2792     Cn 2 rec_trpl 
       
  2793         [Cn 2 rec_newleft [Cn 2 rec_left [id 2 1], 
       
  2794                            Cn 2 rec_right [id 2 1], 
       
  2795                            Cn 2 rec_actn [id 2 0, 
       
  2796                                           Cn 2 rec_stat [id 2 1], 
       
  2797                            Cn 2 rec_right [id 2 1]]],
       
  2798           Cn 2 rec_newstat [id 2 0, 
       
  2799                             Cn 2 rec_stat [id 2 1], 
       
  2800                             Cn 2 rec_right [id 2 1]],
       
  2801            Cn 2 rec_newrght [Cn 2 rec_left [id 2 1], 
       
  2802                              Cn 2 rec_right [id 2 1], 
       
  2803                              Cn 2 rec_actn [id 2 0, 
       
  2804                                    Cn 2 rec_stat [id 2 1], 
       
  2805                              Cn 2 rec_right [id 2 1]]]]"
       
  2806 
       
  2807 lemma newconf_lemma: "rec_exec rec_newconf [m ,c] = newconf m c"
       
  2808 by(auto simp: rec_newconf_def rec_exec.simps 
       
  2809               trpl_lemma newleft_lemma left_lemma
       
  2810               right_lemma stat_lemma newrght_lemma actn_lemma 
       
  2811                newstat_lemma stat_lemma newconf.simps)
       
  2812 
       
  2813 declare newconf_lemma[simp]
       
  2814 
       
  2815 text {*
       
  2816   @{text "conf m r k"} computes the TM configuration after @{text "k"} steps of execution
       
  2817   of TM coded as @{text "m"} starting from the initial configuration where the left number equals @{text "0"}, 
       
  2818   right number equals @{text "r"}. 
       
  2819   *}
       
  2820 fun conf :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2821   where
       
  2822   "conf m r 0 = trpl 0 (Suc 0) r"
       
  2823 | "conf m r (Suc t) = newconf m (conf m r t)"
       
  2824 
       
  2825 declare conf.simps[simp del]
       
  2826 
       
  2827 text {*
       
  2828   @{text "conf"} is implemented by the following recursive function @{text "rec_conf"}.
       
  2829   *}
       
  2830 definition rec_conf :: "recf"
       
  2831   where
       
  2832   "rec_conf = Pr 2 (Cn 2 rec_trpl [Cn 2 (constn 0) [id 2 0], Cn 2 (constn (Suc 0)) [id 2 0], id 2 1])
       
  2833                   (Cn 4 rec_newconf [id 4 0, id 4 3])"
       
  2834 
       
  2835 lemma conf_step: 
       
  2836   "rec_exec rec_conf [m, r, Suc t] =
       
  2837          rec_exec rec_newconf [m, rec_exec rec_conf [m, r, t]]"
       
  2838 proof -
       
  2839   have "rec_exec rec_conf ([m, r] @ [Suc t]) = 
       
  2840           rec_exec rec_newconf [m, rec_exec rec_conf [m, r, t]]"
       
  2841     by(simp only: rec_conf_def rec_pr_Suc_simp_rewrite,
       
  2842         simp add: rec_exec.simps)
       
  2843   thus "rec_exec rec_conf [m, r, Suc t] =
       
  2844                 rec_exec rec_newconf [m, rec_exec rec_conf [m, r, t]]"
       
  2845     by simp
       
  2846 qed
       
  2847 
       
  2848 text {*
       
  2849   The correctness of @{text "rec_conf"}.
       
  2850   *}
       
  2851 lemma conf_lemma: 
       
  2852   "rec_exec rec_conf [m, r, t] = conf m r t"
       
  2853 apply(induct t)
       
  2854 apply(simp add: rec_conf_def rec_exec.simps conf.simps inpt_lemma trpl_lemma)
       
  2855 apply(simp add: conf_step conf.simps)
       
  2856 done
       
  2857 
       
  2858 text {*
       
  2859   @{text "NSTD c"} returns true if the configureation coded by @{text "c"} is no a stardard
       
  2860   final configuration.
       
  2861   *}
       
  2862 fun NSTD :: "nat \<Rightarrow> bool"
       
  2863   where
       
  2864   "NSTD c = (stat c \<noteq> 0 \<or> left c \<noteq> 0 \<or> 
       
  2865              rght c \<noteq> 2^(lg (rght c + 1) 2) - 1 \<or> rght c = 0)"
       
  2866 
       
  2867 text {*
       
  2868   @{text "rec_NSTD"} is the recursive function implementing @{text "NSTD"}.
       
  2869   *}
       
  2870 definition rec_NSTD :: "recf"
       
  2871   where
       
  2872   "rec_NSTD =
       
  2873      Cn 1 rec_disj [
       
  2874           Cn 1 rec_disj [
       
  2875              Cn 1 rec_disj 
       
  2876                 [Cn 1 rec_noteq [rec_stat, constn 0], 
       
  2877                  Cn 1 rec_noteq [rec_left, constn 0]] , 
       
  2878               Cn 1 rec_noteq [rec_right,  
       
  2879                               Cn 1 rec_minus [Cn 1 rec_power 
       
  2880                                  [constn 2, Cn 1 rec_lg 
       
  2881                                     [Cn 1 rec_add        
       
  2882                                      [rec_right, constn 1], 
       
  2883                                             constn 2]], constn 1]]],
       
  2884                Cn 1 rec_eq [rec_right, constn 0]]"
       
  2885 
       
  2886 lemma NSTD_lemma1: "rec_exec rec_NSTD [c] = Suc 0 \<or>
       
  2887                    rec_exec rec_NSTD [c] = 0"
       
  2888 by(simp add: rec_exec.simps rec_NSTD_def)
       
  2889 
       
  2890 declare NSTD.simps[simp del]
       
  2891 lemma NSTD_lemma2': "(rec_exec rec_NSTD [c] = Suc 0) \<Longrightarrow> NSTD c"
       
  2892 apply(simp add: rec_exec.simps rec_NSTD_def stat_lemma left_lemma 
       
  2893                 lg_lemma right_lemma power_lemma NSTD.simps eq_lemma)
       
  2894 apply(auto)
       
  2895 apply(case_tac "0 < left c", simp, simp)
       
  2896 done
       
  2897 
       
  2898 lemma NSTD_lemma2'': 
       
  2899   "NSTD c \<Longrightarrow> (rec_exec rec_NSTD [c] = Suc 0)"
       
  2900 apply(simp add: rec_exec.simps rec_NSTD_def stat_lemma 
       
  2901          left_lemma lg_lemma right_lemma power_lemma NSTD.simps)
       
  2902 apply(auto split: if_splits)
       
  2903 done
       
  2904 
       
  2905 text {*
       
  2906   The correctness of @{text "NSTD"}.
       
  2907   *}
       
  2908 lemma NSTD_lemma2: "(rec_exec rec_NSTD [c] = Suc 0) = NSTD c"
       
  2909 using NSTD_lemma1
       
  2910 apply(auto intro: NSTD_lemma2' NSTD_lemma2'')
       
  2911 done
       
  2912 
       
  2913 fun nstd :: "nat \<Rightarrow> nat"
       
  2914   where
       
  2915   "nstd c = (if NSTD c then 1 else 0)"
       
  2916 
       
  2917 lemma nstd_lemma: "rec_exec rec_NSTD [c] = nstd c"
       
  2918 using NSTD_lemma1
       
  2919 apply(simp add: NSTD_lemma2, auto)
       
  2920 done
       
  2921 
       
  2922 text {* GGGGGGGGGGGGGGGGGGGGGGG *}
       
  2923 
       
  2924 text{* 
       
  2925   @{text "nonstep m r t"} means afer @{text "t"} steps of execution, the TM coded by @{text "m"}
       
  2926   is not at a stardard final configuration.
       
  2927   *}
       
  2928 fun nonstop :: "nat \<Rightarrow> nat  \<Rightarrow> nat \<Rightarrow> nat"
       
  2929   where
       
  2930   "nonstop m r t = nstd (conf m r t)"
       
  2931 
       
  2932 text {*
       
  2933   @{text "rec_nonstop"} is the recursive function implementing @{text "nonstop"}.
       
  2934   *}
       
  2935 definition rec_nonstop :: "recf"
       
  2936   where
       
  2937   "rec_nonstop = Cn 3 rec_NSTD [rec_conf]"
       
  2938 
       
  2939 text {*
       
  2940   The correctness of @{text "rec_nonstop"}.
       
  2941   *}
       
  2942 lemma nonstop_lemma: 
       
  2943   "rec_exec rec_nonstop [m, r, t] = nonstop m r t"
       
  2944 apply(simp add: rec_exec.simps rec_nonstop_def nstd_lemma conf_lemma)
       
  2945 done
       
  2946 
       
  2947 text{*
       
  2948   @{text "rec_halt"} is the recursive function calculating the steps a TM needs to execute before
       
  2949   to reach a stardard final configuration. This recursive function is the only one
       
  2950   using @{text "Mn"} combinator. So it is the only non-primitive recursive function 
       
  2951   needs to be used in the construction of the universal function @{text "F"}.
       
  2952   *}
       
  2953 
       
  2954 definition rec_halt :: "recf"
       
  2955   where
       
  2956   "rec_halt = Mn (Suc (Suc 0)) (rec_nonstop)"
       
  2957 
       
  2958 declare nonstop.simps[simp del]
       
  2959 
       
  2960 (*  when mn, use rec_calc_rel instead of rec_exec*)
       
  2961 
       
  2962 lemma primerec_not0: "primerec f n \<Longrightarrow> n > 0"
       
  2963 by(induct f n rule: primerec.induct, auto)
       
  2964 
       
  2965 lemma [elim]: "primerec f 0 \<Longrightarrow> RR"
       
  2966 apply(drule_tac primerec_not0, simp)
       
  2967 done
       
  2968 
       
  2969 lemma [simp]: "length xs = Suc n \<Longrightarrow> length (butlast xs) = n"
       
  2970 apply(subgoal_tac "\<exists> y ys. xs = ys @ [y]", auto)
       
  2971 apply(rule_tac x = "last xs" in exI)
       
  2972 apply(rule_tac x = "butlast xs" in exI)
       
  2973 apply(case_tac "xs = []", auto)
       
  2974 done
       
  2975 
       
  2976 text {*
       
  2977   The lemma relates the interpreter of primitive fucntions with
       
  2978   the calculation relation of general recursive functions. 
       
  2979   *}
       
  2980 lemma prime_rel_exec_eq: "primerec r (length xs) 
       
  2981            \<Longrightarrow> rec_calc_rel r xs rs = (rec_exec r xs = rs)"
       
  2982 proof(induct r xs arbitrary: rs rule: rec_exec.induct, simp_all)
       
  2983   fix xs rs
       
  2984   assume "primerec z (length (xs::nat list))"
       
  2985   hence "length xs = Suc 0" by(erule_tac prime_z_reverse, simp)
       
  2986   thus "rec_calc_rel z xs rs = (rec_exec z xs = rs)"
       
  2987     apply(case_tac xs, simp, auto)
       
  2988     apply(erule_tac calc_z_reverse, simp add: rec_exec.simps)
       
  2989     apply(simp add: rec_exec.simps, rule_tac calc_z)
       
  2990     done
       
  2991 next
       
  2992   fix xs rs
       
  2993   assume "primerec s (length (xs::nat list))"
       
  2994   hence "length xs = Suc 0" ..
       
  2995   thus "rec_calc_rel s xs rs = (rec_exec s xs = rs)"
       
  2996     by(case_tac xs, auto simp: rec_exec.simps intro: calc_s 
       
  2997                          elim: calc_s_reverse)
       
  2998 next
       
  2999   fix m n xs rs
       
  3000   assume "primerec (recf.id m n) (length (xs::nat list))"
       
  3001   thus
       
  3002     "rec_calc_rel (recf.id m n) xs rs =
       
  3003                    (rec_exec (recf.id m n) xs = rs)"
       
  3004     apply(erule_tac prime_id_reverse)
       
  3005     apply(simp add: rec_exec.simps, auto)
       
  3006     apply(erule_tac calc_id_reverse, simp)
       
  3007     apply(rule_tac calc_id, auto)
       
  3008     done
       
  3009 next
       
  3010   fix n f gs xs rs
       
  3011   assume ind1:
       
  3012     "\<And>x rs. \<lbrakk>x \<in> set gs; primerec x (length xs)\<rbrakk> \<Longrightarrow>
       
  3013                 rec_calc_rel x xs rs = (rec_exec x xs = rs)"
       
  3014     and ind2: 
       
  3015     "\<And>x rs. \<lbrakk>x = map (\<lambda>a. rec_exec a xs) gs; 
       
  3016              primerec f (length gs)\<rbrakk> \<Longrightarrow> 
       
  3017             rec_calc_rel f (map (\<lambda>a. rec_exec a xs) gs) rs = 
       
  3018            (rec_exec f (map (\<lambda>a. rec_exec a xs) gs) = rs)"
       
  3019     and h: "primerec (Cn n f gs) (length xs)"
       
  3020   show "rec_calc_rel (Cn n f gs) xs rs = 
       
  3021                    (rec_exec (Cn n f gs) xs = rs)"
       
  3022   proof(auto simp: rec_exec.simps, erule_tac calc_cn_reverse, auto)
       
  3023     fix ys
       
  3024     assume g1:"\<forall>k<length gs. rec_calc_rel (gs ! k) xs (ys ! k)"
       
  3025       and g2: "length ys = length gs"
       
  3026       and g3: "rec_calc_rel f ys rs"
       
  3027     have "rec_calc_rel f (map (\<lambda>a. rec_exec a xs) gs) rs =
       
  3028                   (rec_exec f (map (\<lambda>a. rec_exec a xs) gs) = rs)"
       
  3029       apply(rule_tac ind2, auto)
       
  3030       using h
       
  3031       apply(erule_tac prime_cn_reverse, simp)
       
  3032       done
       
  3033     moreover have "ys = (map (\<lambda>a. rec_exec a xs) gs)"
       
  3034     proof(rule_tac nth_equalityI, auto simp: g2)
       
  3035       fix i
       
  3036       assume "i < length gs" thus "ys ! i = rec_exec (gs!i) xs"
       
  3037         using ind1[of "gs ! i" "ys ! i"] g1 h
       
  3038         apply(erule_tac prime_cn_reverse, simp)
       
  3039         done
       
  3040     qed     
       
  3041     ultimately show "rec_exec f (map (\<lambda>a. rec_exec a xs) gs) = rs"
       
  3042       using g3
       
  3043       by(simp)
       
  3044   next
       
  3045     from h show 
       
  3046       "rec_calc_rel (Cn n f gs) xs 
       
  3047                  (rec_exec f (map (\<lambda>a. rec_exec a xs) gs))"
       
  3048       apply(rule_tac rs = "(map (\<lambda>a. rec_exec a xs) gs)" in calc_cn, 
       
  3049             auto)
       
  3050       apply(erule_tac [!] prime_cn_reverse, auto)
       
  3051     proof -
       
  3052       fix k
       
  3053       assume "k < length gs" "primerec f (length gs)" 
       
  3054              "\<forall>i<length gs. primerec (gs ! i) (length xs)"
       
  3055       thus "rec_calc_rel (gs ! k) xs (rec_exec (gs ! k) xs)"
       
  3056         using ind1[of "gs!k" "(rec_exec (gs ! k) xs)"]
       
  3057         by(simp)
       
  3058     next
       
  3059       assume "primerec f (length gs)" 
       
  3060              "\<forall>i<length gs. primerec (gs ! i) (length xs)"
       
  3061       thus "rec_calc_rel f (map (\<lambda>a. rec_exec a xs) gs) 
       
  3062         (rec_exec f (map (\<lambda>a. rec_exec a xs) gs))"
       
  3063         using ind2[of "(map (\<lambda>a. rec_exec a xs) gs)" 
       
  3064                    "(rec_exec f (map (\<lambda>a. rec_exec a xs) gs))"]
       
  3065         by simp
       
  3066     qed
       
  3067   qed
       
  3068 next
       
  3069   fix n f g xs rs
       
  3070   assume ind1: 
       
  3071     "\<And>rs. \<lbrakk>last xs = 0; primerec f (length xs - Suc 0)\<rbrakk> 
       
  3072     \<Longrightarrow> rec_calc_rel f (butlast xs) rs = 
       
  3073                      (rec_exec f (butlast xs) = rs)"
       
  3074   and ind2 : 
       
  3075     "\<And>rs. \<lbrakk>0 < last xs; 
       
  3076            primerec (Pr n f g) (Suc (length xs - Suc 0))\<rbrakk> \<Longrightarrow>
       
  3077            rec_calc_rel (Pr n f g) (butlast xs @ [last xs - Suc 0]) rs
       
  3078         = (rec_exec (Pr n f g) (butlast xs @ [last xs - Suc 0]) = rs)"
       
  3079   and ind3: 
       
  3080     "\<And>rs. \<lbrakk>0 < last xs; primerec g (Suc (Suc (length xs - Suc 0)))\<rbrakk>
       
  3081        \<Longrightarrow> rec_calc_rel g (butlast xs @
       
  3082                 [last xs - Suc 0, rec_exec (Pr n f g)
       
  3083                  (butlast xs @ [last xs - Suc 0])]) rs = 
       
  3084               (rec_exec g (butlast xs @ [last xs - Suc 0,
       
  3085                  rec_exec (Pr n f g)  
       
  3086                   (butlast xs @ [last xs - Suc 0])]) = rs)"
       
  3087   and h: "primerec (Pr n f g) (length (xs::nat list))"
       
  3088   show "rec_calc_rel (Pr n f g) xs rs = (rec_exec (Pr n f g) xs = rs)"
       
  3089   proof(auto)
       
  3090     assume "rec_calc_rel (Pr n f g) xs rs"
       
  3091     thus "rec_exec (Pr n f g) xs = rs"
       
  3092     proof(erule_tac calc_pr_reverse)
       
  3093       fix l
       
  3094       assume g: "xs = l @ [0]"
       
  3095                 "rec_calc_rel f l rs" 
       
  3096                 "n = length l"
       
  3097       thus "rec_exec (Pr n f g) xs = rs"
       
  3098         using ind1[of rs] h
       
  3099         apply(simp add: rec_exec.simps, 
       
  3100                   erule_tac prime_pr_reverse, simp)
       
  3101         done
       
  3102     next
       
  3103       fix l y ry
       
  3104       assume d:"xs = l @ [Suc y]" 
       
  3105                "rec_calc_rel (Pr (length l) f g) (l @ [y]) ry"
       
  3106                "n = length l" 
       
  3107                "rec_calc_rel g (l @ [y, ry]) rs"
       
  3108       moreover hence "primerec g (Suc (Suc n))" using h
       
  3109       proof(erule_tac prime_pr_reverse)
       
  3110         assume "primerec g (Suc (Suc n))" "length xs = Suc n"
       
  3111         thus "?thesis" by simp      
       
  3112       qed  
       
  3113       ultimately show "rec_exec (Pr n f g) xs = rs"
       
  3114         apply(simp)
       
  3115         using ind3[of rs]
       
  3116         apply(simp add: rec_pr_Suc_simp_rewrite)
       
  3117         using ind2[of ry] h
       
  3118         apply(simp)
       
  3119         done
       
  3120     qed
       
  3121   next
       
  3122     show "rec_calc_rel (Pr n f g) xs (rec_exec (Pr n f g) xs)"
       
  3123     proof -
       
  3124       have "rec_calc_rel (Pr n f g) (butlast xs @ [last xs])
       
  3125                  (rec_exec (Pr n f g) (butlast xs @ [last xs]))"
       
  3126         using h
       
  3127         apply(erule_tac prime_pr_reverse, simp)
       
  3128         apply(case_tac "last xs", simp)
       
  3129         apply(rule_tac calc_pr_zero, simp)
       
  3130         using ind1[of "rec_exec (Pr n f g) (butlast xs @ [0])"]
       
  3131         apply(simp add: rec_exec.simps, simp, simp, simp)
       
  3132         thm calc_pr_ind
       
  3133         apply(rule_tac rk = "rec_exec (Pr n f g)
       
  3134                (butlast xs@[last xs - Suc 0])" in calc_pr_ind)
       
  3135         using ind2[of "rec_exec (Pr n f g)
       
  3136                  (butlast xs @ [last xs - Suc 0])"] h
       
  3137         apply(simp, simp, simp)
       
  3138       proof -
       
  3139         fix nat
       
  3140         assume "length xs = Suc n" 
       
  3141                "primerec g (Suc (Suc n))" 
       
  3142                "last xs = Suc nat"
       
  3143         thus 
       
  3144           "rec_calc_rel g (butlast xs @ [nat, rec_exec (Pr n f g) 
       
  3145             (butlast xs @ [nat])]) (rec_exec (Pr n f g) (butlast xs @ [Suc nat]))"
       
  3146           using ind3[of "rec_exec (Pr n f g)
       
  3147                                   (butlast xs @ [Suc nat])"]
       
  3148           apply(simp add: rec_exec.simps)
       
  3149           done
       
  3150       qed
       
  3151       thus "rec_calc_rel (Pr n f g) xs (rec_exec (Pr n f g) xs)"
       
  3152         using h
       
  3153         apply(erule_tac prime_pr_reverse, simp)
       
  3154         apply(subgoal_tac "butlast xs @ [last xs] = xs", simp)
       
  3155         apply(case_tac xs, simp, simp)
       
  3156         done
       
  3157     qed
       
  3158   qed
       
  3159 next
       
  3160   fix n f xs rs
       
  3161   assume "primerec (Mn n f) (length (xs::nat list))" 
       
  3162   thus "rec_calc_rel (Mn n f) xs rs = (rec_exec (Mn n f) xs = rs)"
       
  3163     by(erule_tac prime_mn_reverse)
       
  3164 qed
       
  3165         
       
  3166 declare numeral_2_eq_2[simp] numeral_3_eq_3[simp]
       
  3167 
       
  3168 lemma [intro]: "primerec rec_right (Suc 0)"
       
  3169 apply(simp add: rec_right_def rec_lo_def Let_def)
       
  3170 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3171     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3172 done
       
  3173 
       
  3174 lemma [simp]: 
       
  3175 "rec_calc_rel rec_right [r] rs = (rec_exec rec_right [r] = rs)"
       
  3176 apply(rule_tac prime_rel_exec_eq, auto)
       
  3177 done
       
  3178 
       
  3179 lemma [intro]:  "primerec rec_pi (Suc 0)"
       
  3180 apply(simp add: rec_pi_def rec_dummy_pi_def 
       
  3181                 rec_np_def rec_fac_def rec_prime_def
       
  3182                 rec_Minr.simps Let_def get_fstn_args.simps
       
  3183                 arity.simps
       
  3184                 rec_all.simps rec_sigma.simps rec_accum.simps)
       
  3185 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3186     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3187 apply(simp add: rec_dummyfac_def)
       
  3188 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3189     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3190 done
       
  3191 
       
  3192 lemma [intro]: "primerec rec_trpl (Suc (Suc (Suc 0)))"
       
  3193 apply(simp add: rec_trpl_def)
       
  3194 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3195     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3196 done
       
  3197 
       
  3198 lemma [intro!]: "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_listsum2 vl n) vl"
       
  3199 apply(induct n)
       
  3200 apply(simp_all add: rec_strt'.simps Let_def rec_listsum2.simps)
       
  3201 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3202     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3203 done
       
  3204 
       
  3205 lemma [elim]: "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_strt' vl n) vl"
       
  3206 apply(induct n)
       
  3207 apply(simp_all add: rec_strt'.simps Let_def)
       
  3208 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3209     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)
       
  3210 done
       
  3211 
       
  3212 lemma [elim]: "vl > 0 \<Longrightarrow> primerec (rec_strt vl) vl"
       
  3213 apply(simp add: rec_strt.simps rec_strt'.simps)
       
  3214 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3215     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3216 done
       
  3217 
       
  3218 lemma [elim]: 
       
  3219   "i < vl \<Longrightarrow> primerec ((map (\<lambda>i. recf.id (Suc vl) (i)) 
       
  3220         [Suc 0..<vl] @ [recf.id (Suc vl) (vl)]) ! i) (Suc vl)"
       
  3221 apply(induct i, auto simp: nth_append)
       
  3222 done
       
  3223 
       
  3224 lemma [intro]: "primerec rec_newleft0 ((Suc (Suc 0)))"
       
  3225 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  3226                 Let_def arity.simps rec_newleft0_def
       
  3227                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  3228 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3229     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3230 done
       
  3231 
       
  3232 lemma [intro]: "primerec rec_newleft1 ((Suc (Suc 0)))"
       
  3233 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  3234                 Let_def arity.simps rec_newleft0_def
       
  3235                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  3236 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3237     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3238 done
       
  3239 
       
  3240 lemma [intro]: "primerec rec_newleft2 ((Suc (Suc 0)))"
       
  3241 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  3242                 Let_def arity.simps rec_newleft0_def
       
  3243                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  3244 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3245     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3246 done
       
  3247 
       
  3248 lemma [intro]: "primerec rec_newleft3 ((Suc (Suc 0)))"
       
  3249 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  3250                 Let_def arity.simps rec_newleft0_def
       
  3251                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  3252 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3253     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3254 done
       
  3255 
       
  3256 lemma [intro]: "primerec rec_newleft (Suc (Suc (Suc 0)))"
       
  3257 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  3258                 Let_def arity.simps)
       
  3259 apply(rule_tac prime_cn, auto+)
       
  3260 done
       
  3261 
       
  3262 lemma [intro]: "primerec rec_left (Suc 0)"
       
  3263 apply(simp add: rec_left_def rec_lo_def rec_entry_def Let_def)
       
  3264 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3265     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3266 done
       
  3267 
       
  3268 lemma [intro]: "primerec rec_actn (Suc (Suc (Suc 0)))"
       
  3269 apply(simp add: rec_left_def rec_lo_def rec_entry_def
       
  3270                 Let_def rec_actn_def)
       
  3271 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3272     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3273 done
       
  3274 
       
  3275 lemma [intro]: "primerec rec_stat (Suc 0)"
       
  3276 apply(simp add: rec_left_def rec_lo_def rec_entry_def Let_def 
       
  3277                 rec_actn_def rec_stat_def)
       
  3278 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3279     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3280 done
       
  3281 
       
  3282 lemma [intro]: "primerec rec_newstat (Suc (Suc (Suc 0)))"
       
  3283 apply(simp add: rec_left_def rec_lo_def rec_entry_def 
       
  3284                 Let_def rec_actn_def rec_stat_def rec_newstat_def)
       
  3285 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3286     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3287 done
       
  3288 
       
  3289 lemma [intro]: "primerec rec_newrght (Suc (Suc (Suc 0)))"
       
  3290 apply(simp add: rec_newrght_def rec_embranch.simps
       
  3291                 Let_def arity.simps rec_newrgt0_def 
       
  3292                 rec_newrgt1_def rec_newrgt2_def rec_newrgt3_def)
       
  3293 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3294     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3295 done
       
  3296 
       
  3297 lemma [intro]: "primerec rec_newconf (Suc (Suc 0))"
       
  3298 apply(simp add: rec_newconf_def)
       
  3299 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3300     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3301 done
       
  3302 
       
  3303 lemma [intro]: "0 < vl \<Longrightarrow> primerec (rec_inpt (Suc vl)) (Suc vl)"
       
  3304 apply(simp add: rec_inpt_def)
       
  3305 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3306     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3307 done
       
  3308 
       
  3309 lemma [intro]: "primerec rec_conf (Suc (Suc (Suc 0)))"
       
  3310 apply(simp add: rec_conf_def)
       
  3311 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3312     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3313 apply(auto simp: numeral_4_eq_4)
       
  3314 done
       
  3315 
       
  3316 lemma [simp]: 
       
  3317   "rec_calc_rel rec_conf [m, r, t] rs = 
       
  3318                    (rec_exec rec_conf [m, r, t] = rs)"
       
  3319 apply(rule_tac prime_rel_exec_eq, auto)
       
  3320 done
       
  3321 
       
  3322 lemma [intro]: "primerec rec_lg (Suc (Suc 0))"
       
  3323 apply(simp add: rec_lg_def Let_def)
       
  3324 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3325     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3326 done
       
  3327 
       
  3328 lemma [intro]:  "primerec rec_nonstop (Suc (Suc (Suc 0)))"
       
  3329 apply(simp add: rec_nonstop_def rec_NSTD_def rec_stat_def
       
  3330      rec_lo_def Let_def rec_left_def rec_right_def rec_newconf_def
       
  3331      rec_newstat_def)
       
  3332 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3333     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3334 done
       
  3335 
       
  3336 lemma nonstop_eq[simp]: 
       
  3337   "rec_calc_rel rec_nonstop [m, r, t] rs = 
       
  3338                 (rec_exec rec_nonstop [m, r, t] = rs)"
       
  3339 apply(rule prime_rel_exec_eq, auto)
       
  3340 done
       
  3341 
       
  3342 lemma halt_lemma': 
       
  3343   "rec_calc_rel rec_halt [m, r] t = 
       
  3344   (rec_calc_rel rec_nonstop [m, r, t] 0 \<and> 
       
  3345   (\<forall> t'< t. 
       
  3346       (\<exists> y. rec_calc_rel rec_nonstop [m, r, t'] y \<and>
       
  3347             y \<noteq> 0)))"
       
  3348 apply(auto simp: rec_halt_def)
       
  3349 apply(erule calc_mn_reverse, simp)
       
  3350 apply(erule_tac calc_mn_reverse)
       
  3351 apply(erule_tac x = t' in allE, simp)
       
  3352 apply(rule_tac calc_mn, simp_all)
       
  3353 done
       
  3354 
       
  3355 text {*
       
  3356   The following lemma gives the correctness of @{text "rec_halt"}.
       
  3357   It says: if @{text "rec_halt"} calculates that the TM coded by @{text "m"}
       
  3358   will reach a standard final configuration after @{text "t"} steps of execution, then it is indeed so.
       
  3359   *}
       
  3360 lemma halt_lemma:
       
  3361   "rec_calc_rel (rec_halt) [m, r] t = 
       
  3362         (rec_exec rec_nonstop [m, r, t] = 0 \<and> 
       
  3363            (\<forall> t'< t. (\<exists> y. rec_exec rec_nonstop [m, r, t'] = y
       
  3364                     \<and> y \<noteq> 0)))"
       
  3365 using halt_lemma'[of m  r t]
       
  3366 by simp
       
  3367   
       
  3368 text {*F: universal machine*}
       
  3369 
       
  3370 text {*
       
  3371   @{text "valu r"} extracts computing result out of the right number @{text "r"}.
       
  3372   *}
       
  3373 fun valu :: "nat \<Rightarrow> nat"
       
  3374   where
       
  3375   "valu r = (lg (r + 1) 2) - 1"
       
  3376 
       
  3377 text {*
       
  3378   @{text "rec_valu"} is the recursive function implementing @{text "valu"}.
       
  3379 *}
       
  3380 definition rec_valu :: "recf"
       
  3381   where
       
  3382   "rec_valu = Cn 1 rec_minus [Cn 1 rec_lg [s, constn 2], constn 1]"
       
  3383 
       
  3384 text {*
       
  3385   The correctness of @{text "rec_valu"}.
       
  3386 *}
       
  3387 lemma value_lemma: "rec_exec rec_valu [r] = valu r"
       
  3388 apply(simp add: rec_exec.simps rec_valu_def lg_lemma)
       
  3389 done
       
  3390 
       
  3391 lemma [intro]: "primerec rec_valu (Suc 0)"
       
  3392 apply(simp add: rec_valu_def)
       
  3393 apply(rule_tac k = "Suc (Suc 0)" in prime_cn)
       
  3394 apply(auto simp: prime_s)
       
  3395 proof -
       
  3396   show "primerec rec_lg (Suc (Suc 0))" by auto
       
  3397 next
       
  3398   show "Suc (Suc 0) = Suc (Suc 0)" by simp
       
  3399 next
       
  3400   show "primerec (constn (Suc (Suc 0))) (Suc 0)" by auto
       
  3401 qed
       
  3402 
       
  3403 lemma [simp]: "rec_calc_rel rec_valu [r] rs = 
       
  3404                          (rec_exec rec_valu [r] = rs)"
       
  3405 apply(rule_tac prime_rel_exec_eq, auto)
       
  3406 done
       
  3407 
       
  3408 declare valu.simps[simp del]
       
  3409 
       
  3410 text {*
       
  3411   The definition of the universal function @{text "rec_F"}.
       
  3412   *}
       
  3413 definition rec_F :: "recf"
       
  3414   where
       
  3415   "rec_F = Cn (Suc (Suc 0)) rec_valu [Cn (Suc (Suc 0)) rec_right [Cn (Suc (Suc 0))
       
  3416  rec_conf ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])]]"
       
  3417 
       
  3418 lemma get_fstn_args_nth: 
       
  3419   "k < n \<Longrightarrow> (get_fstn_args m n ! k) = id m (k)"
       
  3420 apply(induct n, simp)
       
  3421 apply(case_tac "k = n", simp_all add: get_fstn_args.simps 
       
  3422                                       nth_append)
       
  3423 done
       
  3424 
       
  3425 lemma [simp]: 
       
  3426   "\<lbrakk>ys \<noteq> [];  k < length ys\<rbrakk> \<Longrightarrow>
       
  3427   (get_fstn_args (length ys) (length ys) ! k) = 
       
  3428                                   id (length ys) (k)"
       
  3429 by(erule_tac get_fstn_args_nth)
       
  3430 
       
  3431 lemma calc_rel_get_pren: 
       
  3432   "\<lbrakk>ys \<noteq> [];  k < length ys\<rbrakk> \<Longrightarrow> 
       
  3433   rec_calc_rel (get_fstn_args (length ys) (length ys) ! k) ys
       
  3434                                                             (ys ! k)"
       
  3435 apply(simp)
       
  3436 apply(rule_tac calc_id, auto)
       
  3437 done
       
  3438 
       
  3439 lemma [elim]:
       
  3440   "\<lbrakk>xs \<noteq> []; k < Suc (length xs)\<rbrakk> \<Longrightarrow> 
       
  3441   rec_calc_rel (get_fstn_args (Suc (length xs)) 
       
  3442               (Suc (length xs)) ! k) (m # xs) ((m # xs) ! k)"
       
  3443 using calc_rel_get_pren[of "m#xs" k]
       
  3444 apply(simp)
       
  3445 done
       
  3446 
       
  3447 text {*
       
  3448   The correctness of @{text "rec_F"}, halt case.
       
  3449   *}
       
  3450 lemma  F_lemma: 
       
  3451   "rec_calc_rel rec_halt [m, r] t \<Longrightarrow>
       
  3452   rec_calc_rel rec_F [m, r] (valu (rght (conf m r t)))"
       
  3453 apply(simp add: rec_F_def)
       
  3454 apply(rule_tac  rs = "[rght (conf m r t)]" in calc_cn, 
       
  3455       auto simp: value_lemma)
       
  3456 apply(rule_tac rs = "[conf m r t]" in calc_cn,
       
  3457       auto simp: right_lemma)
       
  3458 apply(rule_tac rs = "[m, r, t]" in calc_cn, auto)
       
  3459 apply(subgoal_tac " k = 0 \<or>  k = Suc 0 \<or> k = Suc (Suc 0)",
       
  3460       auto simp:nth_append)
       
  3461 apply(rule_tac [1-2] calc_id, simp_all add: conf_lemma)
       
  3462 done
       
  3463 
       
  3464 
       
  3465 text {*
       
  3466   The correctness of @{text "rec_F"}, nonhalt case.
       
  3467   *}
       
  3468 lemma F_lemma2: 
       
  3469   "\<forall> t. \<not> rec_calc_rel rec_halt [m, r] t \<Longrightarrow> 
       
  3470                 \<forall> rs. \<not> rec_calc_rel rec_F [m, r] rs"
       
  3471 apply(auto simp: rec_F_def)
       
  3472 apply(erule_tac calc_cn_reverse, simp (no_asm_use))+
       
  3473 proof -
       
  3474   fix rs rsa rsb rsc
       
  3475   assume h:
       
  3476     "\<forall>t. \<not> rec_calc_rel rec_halt [m, r] t" 
       
  3477     "length rsa = Suc 0" 
       
  3478     "rec_calc_rel rec_valu rsa rs" 
       
  3479     "length rsb = Suc 0" 
       
  3480     "rec_calc_rel rec_right rsb (rsa ! 0)"
       
  3481     "length rsc = (Suc (Suc (Suc 0)))"
       
  3482     "rec_calc_rel rec_conf rsc (rsb ! 0)"
       
  3483     and g: "\<forall>k<Suc (Suc (Suc 0)). rec_calc_rel ([recf.id (Suc (Suc 0)) 0, 
       
  3484           recf.id (Suc (Suc 0)) (Suc 0), rec_halt] ! k) [m, r] (rsc ! k)"
       
  3485   have "rec_calc_rel (rec_halt ) [m, r]
       
  3486                               (rsc ! (Suc (Suc 0)))"
       
  3487     using g
       
  3488     apply(erule_tac x = "(Suc (Suc 0))" in allE)
       
  3489     apply(simp add:nth_append)
       
  3490     done
       
  3491   thus "False"
       
  3492     using h
       
  3493     apply(erule_tac x = "ysb ! (Suc (Suc 0))" in allE, simp)
       
  3494     done
       
  3495 qed
       
  3496 
       
  3497 section {* Coding function of TMs *}
       
  3498 
       
  3499 text {*
       
  3500   The purpose of this section is to get the coding function of Turing Machine, which is 
       
  3501   going to be named @{text "code"}.
       
  3502   *}
       
  3503 
       
  3504 fun bl2nat :: "block list \<Rightarrow> nat \<Rightarrow> nat"
       
  3505   where
       
  3506   "bl2nat [] n = 0"
       
  3507 | "bl2nat (Bk#bl) n = bl2nat bl (Suc n)"
       
  3508 | "bl2nat (Oc#bl) n = 2^n + bl2nat bl (Suc n)"
       
  3509 
       
  3510 fun bl2wc :: "block list \<Rightarrow> nat"
       
  3511   where
       
  3512   "bl2wc xs = bl2nat xs 0"
       
  3513 
       
  3514 fun trpl_code :: "t_conf \<Rightarrow> nat"
       
  3515   where
       
  3516   "trpl_code (st, l, r) = trpl (bl2wc l) st (bl2wc r)"
       
  3517 
       
  3518 declare bl2nat.simps[simp del] bl2wc.simps[simp del]
       
  3519         trpl_code.simps[simp del]
       
  3520 
       
  3521 fun action_map :: "taction \<Rightarrow> nat"
       
  3522   where
       
  3523   "action_map W0 = 0"
       
  3524 | "action_map W1 = 1"
       
  3525 | "action_map L = 2"
       
  3526 | "action_map R = 3"
       
  3527 | "action_map Nop = 4"
       
  3528 
       
  3529 fun action_map_iff :: "nat \<Rightarrow> taction"
       
  3530   where
       
  3531   "action_map_iff (0::nat) = W0"
       
  3532 | "action_map_iff (Suc 0) = W1"
       
  3533 | "action_map_iff (Suc (Suc 0)) = L"
       
  3534 | "action_map_iff (Suc (Suc (Suc 0))) = R"
       
  3535 | "action_map_iff n = Nop"
       
  3536 
       
  3537 fun block_map :: "block \<Rightarrow> nat"
       
  3538   where
       
  3539   "block_map Bk = 0"
       
  3540 | "block_map Oc = 1"
       
  3541 
       
  3542 fun godel_code' :: "nat list \<Rightarrow> nat \<Rightarrow> nat"
       
  3543   where
       
  3544   "godel_code' [] n = 1"
       
  3545 | "godel_code' (x#xs) n = (Pi n)^x * godel_code' xs (Suc n) "
       
  3546 
       
  3547 fun godel_code :: "nat list \<Rightarrow> nat"
       
  3548   where
       
  3549   "godel_code xs = (let lh = length xs in 
       
  3550                    2^lh * (godel_code' xs (Suc 0)))"
       
  3551 
       
  3552 fun modify_tprog :: "tprog \<Rightarrow> nat list"
       
  3553   where
       
  3554   "modify_tprog [] =  []"
       
  3555 | "modify_tprog ((ac, ns)#nl) = action_map ac # ns # modify_tprog nl"
       
  3556 
       
  3557 text {*
       
  3558   @{text "code tp"} gives the Godel coding of TM program @{text "tp"}.
       
  3559   *}
       
  3560 fun code :: "tprog \<Rightarrow> nat"
       
  3561   where 
       
  3562   "code tp = (let nl = modify_tprog tp in 
       
  3563               godel_code nl)"
       
  3564 
       
  3565 section {* Relating interperter functions to the execution of TMs *}
       
  3566 
       
  3567 lemma [simp]: "bl2wc [] = 0" by(simp add: bl2wc.simps bl2nat.simps)
       
  3568 term trpl
       
  3569 
       
  3570 lemma [simp]: "\<lbrakk>fetch tp 0 b = (nact, ns)\<rbrakk> \<Longrightarrow> action_map nact = 4"
       
  3571 apply(simp add: fetch.simps)
       
  3572 done
       
  3573 
       
  3574 thm entry_lemma
       
  3575 lemma Pi_gr_1[simp]: "Pi n > Suc 0"
       
  3576 proof(induct n, auto simp: Pi.simps Np.simps)
       
  3577   fix n
       
  3578   let ?setx = "{y. y \<le> Suc (Pi n!) \<and> Pi n < y \<and> Prime y}"
       
  3579   have "finite ?setx" by auto
       
  3580   moreover have "?setx \<noteq> {}"
       
  3581     using prime_ex[of "Pi n"]
       
  3582     apply(auto)
       
  3583     done
       
  3584   ultimately show "Suc 0 < Min ?setx"
       
  3585     apply(simp add: Min_gr_iff)
       
  3586     apply(auto simp: Prime.simps)
       
  3587     done
       
  3588 qed
       
  3589 
       
  3590 lemma Pi_not_0[simp]: "Pi n > 0"
       
  3591 using Pi_gr_1[of n]
       
  3592 by arith
       
  3593 
       
  3594 declare godel_code.simps[simp del]
       
  3595 
       
  3596 lemma [simp]: "0 < godel_code' nl n"
       
  3597 apply(induct nl arbitrary: n)
       
  3598 apply(auto simp: godel_code'.simps)
       
  3599 done
       
  3600 
       
  3601 lemma godel_code_great: "godel_code nl > 0"
       
  3602 apply(simp add: godel_code.simps)
       
  3603 done
       
  3604 
       
  3605 lemma godel_code_eq_1: "(godel_code nl = 1) = (nl = [])"
       
  3606 apply(auto simp: godel_code.simps)
       
  3607 done
       
  3608 
       
  3609 lemma [elim]: 
       
  3610   "\<lbrakk>i < length nl; \<not> Suc 0 < godel_code nl\<rbrakk> \<Longrightarrow> nl ! i = 0"
       
  3611 using godel_code_great[of nl] godel_code_eq_1[of nl]
       
  3612 apply(simp)
       
  3613 done
       
  3614 
       
  3615 term set_of
       
  3616 lemma prime_coprime: "\<lbrakk>Prime x; Prime y; x\<noteq>y\<rbrakk> \<Longrightarrow> coprime x y"
       
  3617 proof(simp only: Prime.simps coprime_nat, auto simp: dvd_def,
       
  3618       rule_tac classical, simp)
       
  3619   fix d k ka
       
  3620   assume case_ka: "\<forall>u<d * ka. \<forall>v<d * ka. u * v \<noteq> d * ka" 
       
  3621     and case_k: "\<forall>u<d * k. \<forall>v<d * k. u * v \<noteq> d * k"
       
  3622     and h: "(0::nat) < d" "d \<noteq> Suc 0" "Suc 0 < d * ka" 
       
  3623            "ka \<noteq> k" "Suc 0 < d * k"
       
  3624   from h have "k > Suc 0 \<or> ka >Suc 0"
       
  3625     apply(auto)
       
  3626     apply(case_tac ka, simp, simp)
       
  3627     apply(case_tac k, simp, simp)
       
  3628     done
       
  3629   from this show "False"
       
  3630   proof(erule_tac disjE)
       
  3631     assume  "(Suc 0::nat) < k"
       
  3632     hence "k < d*k \<and> d < d*k"
       
  3633       using h
       
  3634       by(auto)
       
  3635     thus "?thesis"
       
  3636       using case_k
       
  3637       apply(erule_tac x = d in allE)
       
  3638       apply(simp)
       
  3639       apply(erule_tac x = k in allE)
       
  3640       apply(simp)
       
  3641       done
       
  3642   next
       
  3643     assume "(Suc 0::nat) < ka"
       
  3644     hence "ka < d * ka \<and> d < d*ka"
       
  3645       using h by auto
       
  3646     thus "?thesis"
       
  3647       using case_ka
       
  3648       apply(erule_tac x = d in allE)
       
  3649       apply(simp)
       
  3650       apply(erule_tac x = ka in allE)
       
  3651       apply(simp)
       
  3652       done
       
  3653   qed
       
  3654 qed
       
  3655 
       
  3656 lemma Pi_inc: "Pi (Suc i) > Pi i"
       
  3657 proof(simp add: Pi.simps Np.simps)
       
  3658   let ?setx = "{y. y \<le> Suc (Pi i!) \<and> Pi i < y \<and> Prime y}"
       
  3659   have "finite ?setx" by simp
       
  3660   moreover have "?setx \<noteq> {}"
       
  3661     using prime_ex[of "Pi i"]
       
  3662     apply(auto)
       
  3663     done
       
  3664   ultimately show "Pi i < Min ?setx"
       
  3665     apply(simp add: Min_gr_iff)
       
  3666     done
       
  3667 qed    
       
  3668 
       
  3669 lemma Pi_inc_gr: "i < j \<Longrightarrow> Pi i < Pi j"
       
  3670 proof(induct j, simp)
       
  3671   fix j
       
  3672   assume ind: "i < j \<Longrightarrow> Pi i < Pi j"
       
  3673   and h: "i < Suc j"
       
  3674   from h show "Pi i < Pi (Suc j)"
       
  3675   proof(cases "i < j")
       
  3676     case True thus "?thesis"
       
  3677     proof -
       
  3678       assume "i < j"
       
  3679       hence "Pi i < Pi j" by(erule_tac ind)
       
  3680       moreover have "Pi j < Pi (Suc j)"
       
  3681         apply(simp add: Pi_inc)
       
  3682         done
       
  3683       ultimately show "?thesis"
       
  3684         by simp
       
  3685     qed
       
  3686   next
       
  3687     assume "i < Suc j" "\<not> i < j"
       
  3688     hence "i = j"
       
  3689       by arith
       
  3690     thus "Pi i < Pi (Suc j)"
       
  3691       apply(simp add: Pi_inc)
       
  3692       done
       
  3693   qed
       
  3694 qed      
       
  3695 
       
  3696 lemma Pi_notEq: "i \<noteq> j \<Longrightarrow> Pi i \<noteq> Pi j"
       
  3697 apply(case_tac "i < j")
       
  3698 using Pi_inc_gr[of i j]
       
  3699 apply(simp)
       
  3700 using Pi_inc_gr[of j i]
       
  3701 apply(simp)
       
  3702 done
       
  3703 
       
  3704 lemma [intro]: "Prime (Suc (Suc 0))"
       
  3705 apply(auto simp: Prime.simps)
       
  3706 apply(case_tac u, simp, case_tac nat, simp, simp)
       
  3707 done
       
  3708 
       
  3709 lemma Prime_Pi[intro]: "Prime (Pi n)"
       
  3710 proof(induct n, auto simp: Pi.simps Np.simps)
       
  3711   fix n
       
  3712   let ?setx = "{y. y \<le> Suc (Pi n!) \<and> Pi n < y \<and> Prime y}"
       
  3713   show "Prime (Min ?setx)"
       
  3714   proof -
       
  3715     have "finite ?setx" by simp
       
  3716     moreover have "?setx \<noteq> {}" 
       
  3717       using prime_ex[of "Pi n"]
       
  3718       apply(simp)
       
  3719       done
       
  3720     ultimately show "?thesis"
       
  3721       apply(drule_tac Min_in, simp, simp)
       
  3722       done
       
  3723   qed
       
  3724 qed
       
  3725     
       
  3726 lemma Pi_coprime: "i \<noteq> j \<Longrightarrow> coprime (Pi i) (Pi j)"
       
  3727 using Prime_Pi[of i]
       
  3728 using Prime_Pi[of j]
       
  3729 apply(rule_tac prime_coprime, simp_all add: Pi_notEq)
       
  3730 done
       
  3731 
       
  3732 lemma Pi_power_coprime: "i \<noteq> j \<Longrightarrow> coprime ((Pi i)^m) ((Pi j)^n)"
       
  3733 by(rule_tac coprime_exp2_nat, erule_tac Pi_coprime)
       
  3734 
       
  3735 lemma coprime_dvd_mult_nat2: "\<lbrakk>coprime (k::nat) n; k dvd n * m\<rbrakk> \<Longrightarrow> k dvd m"
       
  3736 apply(erule_tac coprime_dvd_mult_nat)
       
  3737 apply(simp add: dvd_def, auto)
       
  3738 apply(rule_tac x = ka in exI)
       
  3739 apply(subgoal_tac "n * m = m * n", simp)
       
  3740 apply(simp add: nat_mult_commute)
       
  3741 done
       
  3742 
       
  3743 declare godel_code'.simps[simp del]
       
  3744 
       
  3745 lemma godel_code'_butlast_last_id' :
       
  3746   "godel_code' (ys @ [y]) (Suc j) = godel_code' ys (Suc j) * 
       
  3747                                 Pi (Suc (length ys + j)) ^ y"
       
  3748 proof(induct ys arbitrary: j, simp_all add: godel_code'.simps)
       
  3749 qed  
       
  3750 
       
  3751 lemma godel_code'_butlast_last_id: 
       
  3752 "xs \<noteq> [] \<Longrightarrow> godel_code' xs (Suc j) = 
       
  3753   godel_code' (butlast xs) (Suc j) * Pi (length xs + j)^(last xs)"
       
  3754 apply(subgoal_tac "\<exists> ys y. xs = ys @ [y]")
       
  3755 apply(erule_tac exE, erule_tac exE, simp add: 
       
  3756                             godel_code'_butlast_last_id')
       
  3757 apply(rule_tac x = "butlast xs" in exI)
       
  3758 apply(rule_tac x = "last xs" in exI, auto)
       
  3759 done
       
  3760 
       
  3761 lemma godel_code'_not0: "godel_code' xs n \<noteq> 0"
       
  3762 apply(induct xs, auto simp: godel_code'.simps)
       
  3763 done
       
  3764 
       
  3765 lemma godel_code_append_cons: 
       
  3766   "length xs = i \<Longrightarrow> godel_code' (xs@y#ys) (Suc 0)
       
  3767     = godel_code' xs (Suc 0) * Pi (Suc i)^y * godel_code' ys (i + 2)"
       
  3768 proof(induct "length xs" arbitrary: i y ys xs, simp add: godel_code'.simps,simp)
       
  3769   fix x xs i y ys
       
  3770   assume ind: 
       
  3771     "\<And>xs i y ys. \<lbrakk>x = i; length xs = i\<rbrakk> \<Longrightarrow> 
       
  3772        godel_code' (xs @ y # ys) (Suc 0) 
       
  3773      = godel_code' xs (Suc 0) * Pi (Suc i) ^ y * 
       
  3774                              godel_code' ys (Suc (Suc i))"
       
  3775   and h: "Suc x = i" 
       
  3776          "length (xs::nat list) = i"
       
  3777   have 
       
  3778     "godel_code' (butlast xs @ last xs # ((y::nat)#ys)) (Suc 0) = 
       
  3779         godel_code' (butlast xs) (Suc 0) * Pi (Suc (i - 1))^(last xs) 
       
  3780               * godel_code' (y#ys) (Suc (Suc (i - 1)))"
       
  3781     apply(rule_tac ind)
       
  3782     using h
       
  3783     by(auto)
       
  3784   moreover have 
       
  3785     "godel_code' xs (Suc 0)= godel_code' (butlast xs) (Suc 0) *
       
  3786                                                   Pi (i)^(last xs)"
       
  3787     using godel_code'_butlast_last_id[of xs] h
       
  3788     apply(case_tac "xs = []", simp, simp)
       
  3789     done 
       
  3790   moreover have "butlast xs @ last xs # y # ys = xs @ y # ys"
       
  3791     using h
       
  3792     apply(case_tac xs, auto)
       
  3793     done
       
  3794   ultimately show 
       
  3795     "godel_code' (xs @ y # ys) (Suc 0) =
       
  3796                godel_code' xs (Suc 0) * Pi (Suc i) ^ y *
       
  3797                     godel_code' ys (Suc (Suc i))"
       
  3798     using h
       
  3799     apply(simp add: godel_code'_not0 Pi_not_0)
       
  3800     apply(simp add: godel_code'.simps)
       
  3801     done
       
  3802 qed
       
  3803 
       
  3804 lemma Pi_coprime_pre: 
       
  3805   "length ps \<le> i \<Longrightarrow> coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
       
  3806 proof(induct "length ps" arbitrary: ps, simp add: godel_code'.simps)
       
  3807   fix x ps
       
  3808   assume ind: 
       
  3809     "\<And>ps. \<lbrakk>x = length ps; length ps \<le> i\<rbrakk> \<Longrightarrow>
       
  3810                   coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
       
  3811   and h: "Suc x = length ps"
       
  3812           "length (ps::nat list) \<le> i"
       
  3813   have g: "coprime (Pi (Suc i)) (godel_code' (butlast ps) (Suc 0))"
       
  3814     apply(rule_tac ind)
       
  3815     using h by auto
       
  3816   have k: "godel_code' ps (Suc 0) = 
       
  3817          godel_code' (butlast ps) (Suc 0) * Pi (length ps)^(last ps)"
       
  3818     using godel_code'_butlast_last_id[of ps 0] h 
       
  3819     by(case_tac ps, simp, simp)
       
  3820   from g have 
       
  3821     "coprime (Pi (Suc i)) (godel_code' (butlast ps) (Suc 0) *
       
  3822                                         Pi (length ps)^(last ps)) "
       
  3823   proof(rule_tac coprime_mult_nat, simp)
       
  3824     show "coprime (Pi (Suc i)) (Pi (length ps) ^ last ps)"
       
  3825       apply(rule_tac coprime_exp_nat, rule prime_coprime, auto)
       
  3826       using Pi_notEq[of "Suc i" "length ps"] h by simp
       
  3827   qed
       
  3828   from this and k show "coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
       
  3829     by simp
       
  3830 qed
       
  3831 
       
  3832 lemma Pi_coprime_suf: "i < j \<Longrightarrow> coprime (Pi i) (godel_code' ps j)"
       
  3833 proof(induct "length ps" arbitrary: ps, simp add: godel_code'.simps)
       
  3834   fix x ps
       
  3835   assume ind: 
       
  3836     "\<And>ps. \<lbrakk>x = length ps; i < j\<rbrakk> \<Longrightarrow> 
       
  3837                     coprime (Pi i) (godel_code' ps j)"
       
  3838   and h: "Suc x = length (ps::nat list)" "i < j"
       
  3839   have g: "coprime (Pi i) (godel_code' (butlast ps) j)"
       
  3840     apply(rule ind) using h by auto
       
  3841   have k: "(godel_code' ps j) = godel_code' (butlast ps) j *
       
  3842                                  Pi (length ps + j - 1)^last ps"
       
  3843     using h godel_code'_butlast_last_id[of ps "j - 1"]
       
  3844     apply(case_tac "ps = []", simp, simp)
       
  3845     done
       
  3846   from g have
       
  3847     "coprime (Pi i) (godel_code' (butlast ps) j * 
       
  3848                           Pi (length ps + j - 1)^last ps)"
       
  3849     apply(rule_tac coprime_mult_nat, simp)
       
  3850     using  Pi_power_coprime[of i "length ps + j - 1" 1 "last ps"] h
       
  3851     apply(auto)
       
  3852     done
       
  3853   from k and this show "coprime (Pi i) (godel_code' ps j)"
       
  3854     by auto
       
  3855 qed
       
  3856 
       
  3857 lemma godel_finite: 
       
  3858   "finite {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
       
  3859 proof(rule_tac n = "godel_code' nl (Suc 0)" in 
       
  3860                           bounded_nat_set_is_finite, auto, 
       
  3861       case_tac "ia < godel_code' nl (Suc 0)", auto)
       
  3862   fix ia 
       
  3863   assume g1: "Pi (Suc i) ^ ia dvd godel_code' nl (Suc 0)"
       
  3864     and g2: "\<not> ia < godel_code' nl (Suc 0)"
       
  3865   from g1 have "Pi (Suc i)^ia \<le> godel_code' nl (Suc 0)"
       
  3866     apply(erule_tac dvd_imp_le)
       
  3867     using  godel_code'_not0[of nl "Suc 0"] by simp
       
  3868   moreover have "ia < Pi (Suc i)^ia"
       
  3869     apply(rule x_less_exp)
       
  3870     using Pi_gr_1 by auto
       
  3871   ultimately show "False"
       
  3872     using g2
       
  3873     by(auto)
       
  3874 qed
       
  3875 
       
  3876 
       
  3877 lemma godel_code_in: 
       
  3878   "i < length nl \<Longrightarrow>  nl ! i  \<in> {u. Pi (Suc i) ^ u dvd
       
  3879                                      godel_code' nl (Suc 0)}"
       
  3880 proof -
       
  3881  assume h: "i<length nl"
       
  3882   hence "godel_code' (take i nl@(nl!i)#drop (Suc i) nl) (Suc 0)
       
  3883            = godel_code' (take i nl) (Suc 0) *  Pi (Suc i)^(nl!i) *
       
  3884                                godel_code' (drop (Suc i) nl) (i + 2)"
       
  3885     by(rule_tac godel_code_append_cons, simp)
       
  3886   moreover from h have "take i nl @ (nl ! i) # drop (Suc i) nl = nl"
       
  3887     using upd_conv_take_nth_drop[of i nl "nl ! i"]
       
  3888     apply(simp)
       
  3889     done
       
  3890   ultimately  show 
       
  3891     "nl ! i \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
       
  3892     by(simp)
       
  3893 qed
       
  3894      
       
  3895 lemma godel_code'_get_nth:
       
  3896   "i < length nl \<Longrightarrow> Max {u. Pi (Suc i) ^ u dvd 
       
  3897                           godel_code' nl (Suc 0)} = nl ! i"
       
  3898 proof(rule_tac Max_eqI)
       
  3899   let ?gc = "godel_code' nl (Suc 0)"
       
  3900   assume h: "i < length nl" thus "finite {u. Pi (Suc i) ^ u dvd ?gc}"
       
  3901     by (simp add: godel_finite)  
       
  3902 next
       
  3903   fix y
       
  3904   let ?suf ="godel_code' (drop (Suc i) nl) (i + 2)"
       
  3905   let ?pref = "godel_code' (take i nl) (Suc 0)"
       
  3906   assume h: "i < length nl" 
       
  3907             "y \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
       
  3908   moreover hence
       
  3909     "godel_code' (take i nl@(nl!i)#drop (Suc i) nl) (Suc 0)
       
  3910     = ?pref * Pi (Suc i)^(nl!i) * ?suf"
       
  3911     by(rule_tac godel_code_append_cons, simp)
       
  3912   moreover from h have "take i nl @ (nl!i) # drop (Suc i) nl = nl"
       
  3913     using upd_conv_take_nth_drop[of i nl "nl!i"]
       
  3914     by simp
       
  3915   ultimately show "y\<le>nl!i"
       
  3916   proof(simp)
       
  3917     let ?suf' = "godel_code' (drop (Suc i) nl) (Suc (Suc i))"
       
  3918     assume mult_dvd: 
       
  3919       "Pi (Suc i) ^ y dvd ?pref *  Pi (Suc i) ^ nl ! i * ?suf'"
       
  3920     hence "Pi (Suc i) ^ y dvd ?pref * Pi (Suc i) ^ nl ! i"
       
  3921     proof(rule_tac coprime_dvd_mult_nat)
       
  3922       show "coprime (Pi (Suc i)^y) ?suf'"
       
  3923       proof -
       
  3924         have "coprime (Pi (Suc i) ^ y) (?suf'^(Suc 0))"
       
  3925           apply(rule_tac coprime_exp2_nat)
       
  3926           apply(rule_tac  Pi_coprime_suf, simp)
       
  3927           done
       
  3928         thus "?thesis" by simp
       
  3929       qed
       
  3930     qed
       
  3931     hence "Pi (Suc i) ^ y dvd Pi (Suc i) ^ nl ! i"
       
  3932     proof(rule_tac coprime_dvd_mult_nat2)
       
  3933       show "coprime (Pi (Suc i) ^ y) ?pref"
       
  3934       proof -
       
  3935         have "coprime (Pi (Suc i)^y) (?pref^Suc 0)"
       
  3936           apply(rule_tac coprime_exp2_nat)
       
  3937           apply(rule_tac Pi_coprime_pre, simp)
       
  3938           done
       
  3939         thus "?thesis" by simp
       
  3940       qed
       
  3941     qed
       
  3942     hence "Pi (Suc i) ^ y \<le>  Pi (Suc i) ^ nl ! i "
       
  3943       apply(rule_tac dvd_imp_le, auto)
       
  3944       done
       
  3945     thus "y \<le> nl ! i"
       
  3946       apply(rule_tac power_le_imp_le_exp, auto)
       
  3947       done
       
  3948   qed
       
  3949 next
       
  3950   assume h: "i<length nl"
       
  3951   thus "nl ! i \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
       
  3952     by(rule_tac godel_code_in, simp)
       
  3953 qed
       
  3954 
       
  3955 lemma [simp]: 
       
  3956   "{u. Pi (Suc i) ^ u dvd (Suc (Suc 0)) ^ length nl * 
       
  3957                                      godel_code' nl (Suc 0)} = 
       
  3958     {u. Pi (Suc i) ^ u dvd  godel_code' nl (Suc 0)}"
       
  3959 apply(rule_tac Collect_cong, auto)
       
  3960 apply(rule_tac n = " (Suc (Suc 0)) ^ length nl" in 
       
  3961                                  coprime_dvd_mult_nat2)
       
  3962 proof -
       
  3963   fix u
       
  3964   show "coprime (Pi (Suc i) ^ u) ((Suc (Suc 0)) ^ length nl)"
       
  3965   proof(rule_tac coprime_exp2_nat)
       
  3966     have "Pi 0 = (2::nat)"
       
  3967       apply(simp add: Pi.simps)
       
  3968       done
       
  3969     moreover have "coprime (Pi (Suc i)) (Pi 0)"
       
  3970       apply(rule_tac Pi_coprime, simp)
       
  3971       done
       
  3972     ultimately show "coprime (Pi (Suc i)) (Suc (Suc 0))" by simp
       
  3973   qed
       
  3974 qed
       
  3975   
       
  3976 lemma godel_code_get_nth: 
       
  3977   "i < length nl \<Longrightarrow> 
       
  3978            Max {u. Pi (Suc i) ^ u dvd godel_code nl} = nl ! i"
       
  3979 by(simp add: godel_code.simps godel_code'_get_nth)
       
  3980 
       
  3981 thm trpl.simps
       
  3982 
       
  3983 lemma "trpl l st r = godel_code' [l, st, r] 0"
       
  3984 apply(simp add: trpl.simps godel_code'.simps)
       
  3985 done
       
  3986 
       
  3987 lemma mod_dvd_simp: "(x mod y = (0::nat)) = (y dvd x)"
       
  3988 by(simp add: dvd_def, auto)
       
  3989 
       
  3990 lemma dvd_power_le: "\<lbrakk>a > Suc 0; a ^ y dvd a ^ l\<rbrakk> \<Longrightarrow> y \<le> l"
       
  3991 apply(case_tac "y \<le> l", simp, simp)
       
  3992 apply(subgoal_tac "\<exists> d. y = l + d", auto simp: power_add)
       
  3993 apply(rule_tac x = "y - l" in exI, simp)
       
  3994 done
       
  3995 
       
  3996 
       
  3997 lemma [elim]: "Pi n = 0 \<Longrightarrow> RR"
       
  3998   using Pi_not_0[of n] by simp
       
  3999 
       
  4000 lemma [elim]: "Pi n = Suc 0 \<Longrightarrow> RR"
       
  4001   using Pi_gr_1[of n] by simp
       
  4002 
       
  4003 lemma finite_power_dvd:
       
  4004   "\<lbrakk>(a::nat) > Suc 0; y \<noteq> 0\<rbrakk> \<Longrightarrow> finite {u. a^u dvd y}"
       
  4005 apply(auto simp: dvd_def)
       
  4006 apply(rule_tac n = y in bounded_nat_set_is_finite, auto)
       
  4007 apply(case_tac k, simp,simp)
       
  4008 apply(rule_tac trans_less_add1)
       
  4009 apply(erule_tac x_less_exp)
       
  4010 done
       
  4011 
       
  4012 lemma conf_decode1: "\<lbrakk>m \<noteq> n; m \<noteq> k; k \<noteq> n\<rbrakk> \<Longrightarrow> 
       
  4013   Max {u. Pi m ^ u dvd Pi m ^ l * Pi n ^ st * Pi k ^ r} = l"
       
  4014 proof -
       
  4015   let ?setx = "{u. Pi m ^ u dvd Pi m ^ l * Pi n ^ st * Pi k ^ r}"
       
  4016   assume g: "m \<noteq> n" "m \<noteq> k" "k \<noteq> n"
       
  4017   show "Max ?setx = l"
       
  4018   proof(rule_tac Max_eqI)
       
  4019     show "finite ?setx"
       
  4020       apply(rule_tac finite_power_dvd, auto simp: Pi_gr_1)
       
  4021       done
       
  4022   next
       
  4023     fix y
       
  4024     assume h: "y \<in> ?setx"
       
  4025     have "Pi m ^ y dvd Pi m ^ l"
       
  4026     proof -
       
  4027       have "Pi m ^ y dvd Pi m ^ l * Pi n ^ st"
       
  4028         using h g
       
  4029         apply(rule_tac n = "Pi k^r" in coprime_dvd_mult_nat)
       
  4030         apply(rule Pi_power_coprime, simp, simp)
       
  4031         done
       
  4032       thus "Pi m^y dvd Pi m^l"
       
  4033         apply(rule_tac n = " Pi n ^ st" in coprime_dvd_mult_nat)
       
  4034         using g
       
  4035         apply(rule_tac Pi_power_coprime, simp, simp)
       
  4036         done
       
  4037     qed
       
  4038     thus "y \<le> (l::nat)"
       
  4039       apply(rule_tac a = "Pi m" in power_le_imp_le_exp)
       
  4040       apply(simp_all add: Pi_gr_1)
       
  4041       apply(rule_tac dvd_power_le, auto)
       
  4042       done
       
  4043   next
       
  4044     show "l \<in> ?setx" by simp
       
  4045   qed
       
  4046 qed  
       
  4047 
       
  4048 lemma conf_decode2: 
       
  4049   "\<lbrakk>m \<noteq> n; m \<noteq> k; n \<noteq> k; 
       
  4050   \<not> Suc 0 < Pi m ^ l * Pi n ^ st * Pi k ^ r\<rbrakk> \<Longrightarrow> l = 0"
       
  4051 apply(case_tac "Pi m ^ l * Pi n ^ st * Pi k ^ r", auto)
       
  4052 done
       
  4053 
       
  4054 lemma [simp]: "left (trpl l st r) = l"
       
  4055 apply(simp add: left.simps trpl.simps lo.simps 
       
  4056               loR.simps mod_dvd_simp, auto simp: conf_decode1)
       
  4057 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r",
       
  4058       auto)
       
  4059 apply(erule_tac x = l in allE, auto)
       
  4060 done   
       
  4061 
       
  4062 lemma [simp]: "stat (trpl l st r) = st"
       
  4063 apply(simp add: stat.simps trpl.simps lo.simps 
       
  4064                 loR.simps mod_dvd_simp, auto)
       
  4065 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r
       
  4066                = Pi (Suc 0)^st * Pi 0 ^ l *  Pi (Suc (Suc 0)) ^ r")
       
  4067 apply(simp (no_asm_simp) add: conf_decode1, simp)
       
  4068 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * 
       
  4069                                   Pi (Suc (Suc 0)) ^ r", auto)
       
  4070 apply(erule_tac x = st in allE, auto)
       
  4071 done
       
  4072 
       
  4073 lemma [simp]: "rght (trpl l st r) = r"
       
  4074 apply(simp add: rght.simps trpl.simps lo.simps 
       
  4075                 loR.simps mod_dvd_simp, auto)
       
  4076 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r
       
  4077                = Pi (Suc (Suc 0))^r * Pi 0 ^ l *  Pi (Suc 0) ^ st")
       
  4078 apply(simp (no_asm_simp) add: conf_decode1, simp)
       
  4079 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r",
       
  4080        auto)
       
  4081 apply(erule_tac x = r in allE, auto)
       
  4082 done
       
  4083 
       
  4084 lemma max_lor:
       
  4085   "i < length nl \<Longrightarrow> Max {u. loR [godel_code nl, Pi (Suc i), u]} 
       
  4086                    = nl ! i"
       
  4087 apply(simp add: loR.simps godel_code_get_nth mod_dvd_simp)
       
  4088 done
       
  4089 
       
  4090 lemma godel_decode: 
       
  4091   "i < length nl \<Longrightarrow> Entry (godel_code nl) i = nl ! i"
       
  4092 apply(auto simp: Entry.simps lo.simps max_lor)
       
  4093 apply(erule_tac x = "nl!i" in allE)
       
  4094 using max_lor[of i nl] godel_finite[of i nl]
       
  4095 apply(simp)
       
  4096 apply(drule_tac Max_in, auto simp: loR.simps 
       
  4097                    godel_code.simps mod_dvd_simp)
       
  4098 using godel_code_in[of i nl]
       
  4099 apply(simp)
       
  4100 done
       
  4101 
       
  4102 lemma Four_Suc: "4 = Suc (Suc (Suc (Suc 0)))"
       
  4103 by auto
       
  4104 
       
  4105 declare numeral_2_eq_2[simp del]
       
  4106 
       
  4107 lemma modify_tprog_fetch_even: 
       
  4108   "\<lbrakk>st \<le> length tp div 2; st > 0\<rbrakk> \<Longrightarrow>
       
  4109   modify_tprog tp ! (4 * (st - Suc 0) ) = 
       
  4110   action_map (fst (tp ! (2 * (st - Suc 0))))"
       
  4111 proof(induct st arbitrary: tp, simp)
       
  4112   fix tp st
       
  4113   assume ind: 
       
  4114     "\<And>tp. \<lbrakk>st \<le> length tp div 2; 0 < st\<rbrakk> \<Longrightarrow> 
       
  4115      modify_tprog tp ! (4 * (st - Suc 0)) =
       
  4116                action_map (fst ((tp::tprog) ! (2 * (st - Suc 0))))"
       
  4117   and h: "Suc st \<le> length (tp::tprog) div 2" "0 < Suc st"
       
  4118   thus "modify_tprog tp ! (4 * (Suc st - Suc 0)) = 
       
  4119           action_map (fst (tp ! (2 * (Suc st - Suc 0))))"
       
  4120   proof(cases "st = 0")
       
  4121     case True thus "?thesis"
       
  4122       using h
       
  4123       apply(auto)
       
  4124       apply(cases tp, simp, case_tac a, simp add: modify_tprog.simps)
       
  4125       done
       
  4126   next
       
  4127     case False
       
  4128     assume g: "st \<noteq> 0"
       
  4129     hence "\<exists> aa ab ba bb tp'. tp = (aa, ab) # (ba, bb) # tp'"
       
  4130       using h
       
  4131       apply(case_tac tp, simp, case_tac list, simp, simp)
       
  4132       done
       
  4133     from this obtain aa ab ba bb tp' where g1: 
       
  4134       "tp = (aa, ab) # (ba, bb) # tp'" by blast
       
  4135     hence g2: 
       
  4136       "modify_tprog tp' ! (4 * (st - Suc 0)) = 
       
  4137       action_map (fst ((tp'::tprog) ! (2 * (st - Suc 0))))"
       
  4138       apply(rule_tac ind)
       
  4139       using h g by auto
       
  4140     thus "?thesis"
       
  4141       using g1 g
       
  4142       apply(case_tac st, simp, simp add: Four_Suc)
       
  4143       done
       
  4144   qed
       
  4145 qed
       
  4146       
       
  4147 lemma modify_tprog_fetch_odd: 
       
  4148   "\<lbrakk>st \<le> length tp div 2; st > 0\<rbrakk> \<Longrightarrow> 
       
  4149        modify_tprog tp ! (Suc (Suc (4 * (st - Suc 0)))) = 
       
  4150        action_map (fst (tp ! (Suc (2 * (st - Suc 0)))))"
       
  4151 proof(induct st arbitrary: tp, simp)
       
  4152   fix tp st
       
  4153   assume ind: 
       
  4154     "\<And>tp. \<lbrakk>st \<le> length tp div 2; 0 < st\<rbrakk> \<Longrightarrow>  
       
  4155        modify_tprog tp ! Suc (Suc (4 * (st - Suc 0))) = 
       
  4156           action_map (fst (tp ! Suc (2 * (st - Suc 0))))"
       
  4157   and h: "Suc st \<le> length (tp::tprog) div 2" "0 < Suc st"
       
  4158   thus "modify_tprog tp ! Suc (Suc (4 * (Suc st - Suc 0))) 
       
  4159      = action_map (fst (tp ! Suc (2 * (Suc st - Suc 0))))"
       
  4160   proof(cases "st = 0")
       
  4161     case True thus "?thesis"
       
  4162       using h
       
  4163       apply(auto)
       
  4164       apply(cases tp, simp, case_tac a, simp add: modify_tprog.simps)
       
  4165       apply(case_tac list, simp, case_tac ab,
       
  4166              simp add: modify_tprog.simps)
       
  4167       done
       
  4168   next
       
  4169     case False
       
  4170     assume g: "st \<noteq> 0"
       
  4171     hence "\<exists> aa ab ba bb tp'. tp = (aa, ab) # (ba, bb) # tp'"
       
  4172       using h
       
  4173       apply(case_tac tp, simp, case_tac list, simp, simp)
       
  4174       done
       
  4175     from this obtain aa ab ba bb tp' where g1: 
       
  4176       "tp = (aa, ab) # (ba, bb) # tp'" by blast
       
  4177     hence g2: "modify_tprog tp' ! Suc (Suc (4 * (st  - Suc 0))) = 
       
  4178           action_map (fst (tp' ! Suc (2 * (st - Suc 0))))"
       
  4179       apply(rule_tac ind)
       
  4180       using h g by auto
       
  4181     thus "?thesis"
       
  4182       using g1 g
       
  4183       apply(case_tac st, simp, simp add: Four_Suc)
       
  4184       done
       
  4185   qed
       
  4186 qed    
       
  4187          
       
  4188 lemma modify_tprog_fetch_action:
       
  4189   "\<lbrakk>st \<le> length tp div 2; st > 0; b = 1 \<or> b = 0\<rbrakk> \<Longrightarrow> 
       
  4190       modify_tprog tp ! (4 * (st - Suc 0) + 2* b) =
       
  4191       action_map (fst (tp ! ((2 * (st - Suc 0)) + b)))"
       
  4192 apply(erule_tac disjE, auto elim: modify_tprog_fetch_odd
       
  4193                                    modify_tprog_fetch_even)
       
  4194 done 
       
  4195 
       
  4196 lemma length_modify: "length (modify_tprog tp) = 2 * length tp"
       
  4197 apply(induct tp, auto)
       
  4198 done
       
  4199 
       
  4200 declare fetch.simps[simp del]
       
  4201 
       
  4202 lemma fetch_action_eq: 
       
  4203   "\<lbrakk>block_map b = scan r; fetch tp st b = (nact, ns);
       
  4204    st \<le> length tp div 2\<rbrakk> \<Longrightarrow> actn (code tp) st r = action_map nact"
       
  4205 proof(simp add: actn.simps, auto)
       
  4206   let ?i = "4 * (st - Suc 0) + 2 * (r mod 2)"
       
  4207   assume h: "block_map b = r mod 2" "fetch tp st b = (nact, ns)" 
       
  4208             "st \<le> length tp div 2" "0 < st"
       
  4209   have "?i < length (modify_tprog tp)"
       
  4210   proof -
       
  4211     have "length (modify_tprog tp) = 2 * length tp"
       
  4212       by(simp add: length_modify)
       
  4213     thus "?thesis"
       
  4214       using h
       
  4215       by(auto)
       
  4216   qed
       
  4217   hence 
       
  4218     "Entry (godel_code (modify_tprog tp))?i = 
       
  4219                                    (modify_tprog tp) ! ?i"
       
  4220     by(erule_tac godel_decode)
       
  4221   thm modify_tprog.simps
       
  4222   moreover have 
       
  4223     "modify_tprog tp ! ?i = 
       
  4224             action_map (fst (tp ! (2 * (st - Suc 0) + r mod 2)))"
       
  4225     apply(rule_tac  modify_tprog_fetch_action)
       
  4226     using h
       
  4227     by(auto)    
       
  4228   moreover have "(fst (tp ! (2 * (st - Suc 0) + r mod 2))) = nact"
       
  4229     using h
       
  4230     apply(simp add: fetch.simps nth_of.simps)
       
  4231     apply(case_tac b, auto simp: block_map.simps nth_of.simps split: if_splits)
       
  4232     done
       
  4233   ultimately show 
       
  4234     "Entry (godel_code (modify_tprog tp))
       
  4235                       (4 * (st - Suc 0) + 2 * (r mod 2))
       
  4236            = action_map nact" 
       
  4237     by simp
       
  4238 qed
       
  4239 
       
  4240 lemma [simp]: "fetch tp 0 b = (nact, ns) \<Longrightarrow> ns = 0"
       
  4241 by(simp add: fetch.simps)
       
  4242 
       
  4243 lemma Five_Suc: "5 = Suc 4" by simp
       
  4244 
       
  4245 lemma modify_tprog_fetch_state:
       
  4246   "\<lbrakk>st \<le> length tp div 2; st > 0; b = 1 \<or> b = 0\<rbrakk> \<Longrightarrow> 
       
  4247      modify_tprog tp ! Suc (4 * (st - Suc 0) + 2 * b) =
       
  4248   (snd (tp ! (2 * (st - Suc 0) + b)))"
       
  4249 proof(induct st arbitrary: tp, simp)
       
  4250   fix st tp
       
  4251   assume ind: 
       
  4252     "\<And>tp. \<lbrakk>st \<le> length tp div 2; 0 < st; b = 1 \<or> b = 0\<rbrakk> \<Longrightarrow> 
       
  4253     modify_tprog tp ! Suc (4 * (st - Suc 0) + 2 * b) =
       
  4254                              snd (tp ! (2 * (st - Suc 0) + b))"
       
  4255   and h:
       
  4256     "Suc st \<le> length (tp::tprog) div 2" 
       
  4257     "0 < Suc st" 
       
  4258     "b = 1 \<or> b = 0"
       
  4259   show "modify_tprog tp ! Suc (4 * (Suc st - Suc 0) + 2 * b) =
       
  4260                              snd (tp ! (2 * (Suc st - Suc 0) + b))"
       
  4261   proof(cases "st = 0")
       
  4262     case True
       
  4263     thus "?thesis"
       
  4264       using h
       
  4265       apply(cases tp, simp, case_tac a, simp add: modify_tprog.simps)
       
  4266       apply(case_tac list, simp, case_tac ab, 
       
  4267                          simp add: modify_tprog.simps, auto)
       
  4268       done
       
  4269   next
       
  4270     case False
       
  4271     assume g: "st \<noteq> 0"
       
  4272     hence "\<exists> aa ab ba bb tp'. tp = (aa, ab) # (ba, bb) # tp'"
       
  4273       using h
       
  4274       apply(case_tac tp, simp, case_tac list, simp, simp)
       
  4275       done
       
  4276     from this obtain aa ab ba bb tp' where g1:
       
  4277       "tp = (aa, ab) # (ba, bb) # tp'" by blast
       
  4278     hence g2: 
       
  4279       "modify_tprog tp' ! Suc (4 * (st - Suc 0) + 2 * b) =
       
  4280                               snd (tp' ! (2 * (st - Suc 0) + b))"
       
  4281       apply(rule_tac ind)
       
  4282       using h g by auto
       
  4283     thus "?thesis"
       
  4284       using g1 g
       
  4285       apply(case_tac st, simp, simp)
       
  4286       done
       
  4287   qed
       
  4288 qed
       
  4289   
       
  4290 lemma fetch_state_eq:
       
  4291   "\<lbrakk>block_map b = scan r; 
       
  4292   fetch tp st b = (nact, ns);
       
  4293   st \<le> length tp div 2\<rbrakk> \<Longrightarrow> newstat (code tp) st r = ns"
       
  4294 proof(simp add: newstat.simps, auto)
       
  4295   let ?i = "Suc (4 * (st - Suc 0) + 2 * (r mod 2))"
       
  4296   assume h: "block_map b = r mod 2" "fetch tp st b =
       
  4297              (nact, ns)" "st \<le> length tp div 2" "0 < st"
       
  4298   have "?i < length (modify_tprog tp)"
       
  4299   proof -
       
  4300     have "length (modify_tprog tp) = 2 * length tp"
       
  4301       apply(simp add: length_modify)
       
  4302       done
       
  4303     thus "?thesis"
       
  4304       using h
       
  4305       by(auto)
       
  4306   qed
       
  4307   hence "Entry (godel_code (modify_tprog tp)) (?i) = 
       
  4308                                   (modify_tprog tp) ! ?i"
       
  4309     by(erule_tac godel_decode)
       
  4310   thm modify_tprog.simps
       
  4311   moreover have 
       
  4312     "modify_tprog tp ! ?i =  
       
  4313                (snd (tp ! (2 * (st - Suc 0) + r mod 2)))"
       
  4314     apply(rule_tac  modify_tprog_fetch_state)
       
  4315     using h
       
  4316     by(auto)
       
  4317   moreover have "(snd (tp ! (2 * (st - Suc 0) + r mod 2))) = ns"
       
  4318     using h
       
  4319     apply(simp add: fetch.simps nth_of.simps)
       
  4320     apply(case_tac b, auto simp: block_map.simps nth_of.simps
       
  4321                                  split: if_splits)
       
  4322     done
       
  4323   ultimately show "Entry (godel_code (modify_tprog tp)) (?i)
       
  4324            = ns" 
       
  4325     by simp
       
  4326 qed
       
  4327 
       
  4328 
       
  4329 lemma [intro!]: 
       
  4330   "\<lbrakk>a = a'; b = b'; c = c'\<rbrakk> \<Longrightarrow> trpl a b c = trpl a' b' c'"
       
  4331 by simp
       
  4332 
       
  4333 lemma [simp]: "bl2wc [Bk] = 0"
       
  4334 by(simp add: bl2wc.simps bl2nat.simps)
       
  4335 
       
  4336 lemma bl2nat_double: "bl2nat xs (Suc n) = 2 * bl2nat xs n"
       
  4337 proof(induct xs arbitrary: n)
       
  4338   case Nil thus "?case"
       
  4339     by(simp add: bl2nat.simps)
       
  4340 next
       
  4341   case (Cons x xs) thus "?case"
       
  4342   proof -
       
  4343     assume ind: "\<And>n. bl2nat xs (Suc n) = 2 * bl2nat xs n "
       
  4344     show "bl2nat (x # xs) (Suc n) = 2 * bl2nat (x # xs) n"
       
  4345     proof(cases x)
       
  4346       case Bk thus "?thesis"
       
  4347         apply(simp add: bl2nat.simps)
       
  4348         using ind[of "Suc n"] by simp
       
  4349     next
       
  4350       case Oc thus "?thesis"
       
  4351         apply(simp add: bl2nat.simps)
       
  4352         using ind[of "Suc n"] by simp
       
  4353     qed
       
  4354   qed
       
  4355 qed
       
  4356 
       
  4357 
       
  4358 lemma [simp]: "c \<noteq> [] \<Longrightarrow> 2 * bl2wc (tl c) = bl2wc c - bl2wc c mod 2 "
       
  4359 apply(case_tac c, simp, case_tac a)
       
  4360 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4361 done
       
  4362 
       
  4363 lemma [simp]:
       
  4364   "c \<noteq> [] \<Longrightarrow> bl2wc (Oc # tl c) = Suc (bl2wc c) - bl2wc c mod 2 "
       
  4365 apply(case_tac c, simp, case_tac a)
       
  4366 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4367 done
       
  4368 
       
  4369 lemma [simp]: "bl2wc (Bk # c) = 2*bl2wc (c)"
       
  4370 apply(simp add: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4371 done
       
  4372 
       
  4373 lemma [simp]: "bl2wc [Oc] = Suc 0"
       
  4374  by(simp add: bl2wc.simps bl2nat.simps)
       
  4375 
       
  4376 lemma [simp]: "b \<noteq> [] \<Longrightarrow> bl2wc (tl b) = bl2wc b div 2"
       
  4377 apply(case_tac b, simp, case_tac a)
       
  4378 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4379 done
       
  4380 
       
  4381 lemma [simp]: "b \<noteq> [] \<Longrightarrow> bl2wc ([hd b]) = bl2wc b mod 2"
       
  4382 apply(case_tac b, simp, case_tac a)
       
  4383 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4384 done
       
  4385 
       
  4386 lemma [simp]: "\<lbrakk>b \<noteq> []; c \<noteq> []\<rbrakk> \<Longrightarrow> bl2wc (hd b # c) = 2 * bl2wc c + bl2wc b mod 2"
       
  4387 apply(case_tac b, simp, case_tac a)
       
  4388 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4389 done
       
  4390 
       
  4391 lemma [simp]: " 2 * (bl2wc c div 2) = bl2wc c - bl2wc c mod 2" 
       
  4392   by(simp add: mult_div_cancel)
       
  4393 
       
  4394 lemma [simp]: "bl2wc (Oc # list) mod 2 = Suc 0" 
       
  4395   by(simp add: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4396 
       
  4397 
       
  4398 declare code.simps[simp del]
       
  4399 declare nth_of.simps[simp del]
       
  4400 declare new_tape.simps[simp del]
       
  4401 
       
  4402 text {*
       
  4403   The lemma relates the one step execution of TMs with the interpreter function @{text "rec_newconf"}.
       
  4404   *}
       
  4405 lemma rec_t_eq_step: 
       
  4406   "(\<lambda> (s, l, r). s \<le> length tp div 2) c \<Longrightarrow>
       
  4407   trpl_code (tstep c tp) = 
       
  4408   rec_exec rec_newconf [code tp, trpl_code c]"
       
  4409 apply(cases c, auto simp: tstep.simps)
       
  4410 proof(case_tac "fetch tp a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)",
       
  4411       simp add: newconf.simps trpl_code.simps)
       
  4412   fix a b c aa ba
       
  4413   assume h: "(a::nat) \<le> length tp div 2" 
       
  4414     "fetch tp a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x) = (aa, ba)"
       
  4415   moreover hence "actn (code tp) a (bl2wc c) = action_map aa"
       
  4416     apply(rule_tac b = "(case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)" 
       
  4417           in fetch_action_eq, auto)
       
  4418     apply(auto split: list.splits)
       
  4419     apply(case_tac ab, auto)
       
  4420     done
       
  4421   moreover from h have "(newstat (code tp) a (bl2wc c)) = ba"
       
  4422     apply(rule_tac b = "(case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)" 
       
  4423           in fetch_state_eq, auto split: list.splits)
       
  4424     apply(case_tac ab, auto)
       
  4425     done
       
  4426   ultimately show 
       
  4427     "trpl_code (ba, new_tape aa (b, c)) =
       
  4428     trpl (newleft (bl2wc b) (bl2wc c) (actn (code tp) a (bl2wc c))) 
       
  4429     (newstat (code tp) a (bl2wc c)) (newrght (bl2wc b) (bl2wc c) 
       
  4430      (actn  (code tp) a (bl2wc c)))"
       
  4431     by(auto simp: new_tape.simps trpl_code.simps 
       
  4432          newleft.simps newrght.simps split: taction.splits)
       
  4433 qed
       
  4434 
       
  4435 lemma [simp]: "a\<^bsup>0\<^esup> = []"
       
  4436 apply(simp add: exp_zero)
       
  4437 done
       
  4438 lemma [simp]: "bl2nat (Oc # Oc\<^bsup>x\<^esup>) 0 = (2 * 2 ^ x - Suc 0)"
       
  4439 apply(induct x)
       
  4440 apply(simp add: bl2nat.simps)
       
  4441 apply(simp add: bl2nat.simps bl2nat_double exp_ind_def)
       
  4442 done
       
  4443 
       
  4444 lemma [simp]: "bl2nat (Oc\<^bsup>y\<^esup>) 0 = 2^y - Suc 0"
       
  4445 apply(induct y, auto simp: bl2nat.simps exp_ind_def bl2nat_double)
       
  4446 apply(case_tac "(2::nat)^y", auto)
       
  4447 done
       
  4448 
       
  4449 lemma [simp]: "bl2nat (Bk\<^bsup>l\<^esup>) n = 0"
       
  4450 apply(induct l, auto simp: bl2nat.simps bl2nat_double exp_ind_def)
       
  4451 done
       
  4452 
       
  4453 lemma bl2nat_cons_bk: "bl2nat (ks @ [Bk]) 0 = bl2nat ks 0"
       
  4454 apply(induct ks, auto simp: bl2nat.simps split: block.splits)
       
  4455 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double)
       
  4456 done
       
  4457 
       
  4458 lemma bl2nat_cons_oc:
       
  4459   "bl2nat (ks @ [Oc]) 0 =  bl2nat ks 0 + 2 ^ length ks"
       
  4460 apply(induct ks, auto simp: bl2nat.simps split: block.splits)
       
  4461 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double)
       
  4462 done
       
  4463 
       
  4464 lemma bl2nat_append: 
       
  4465   "bl2nat (xs @ ys) 0 = bl2nat xs 0 + bl2nat ys (length xs) "
       
  4466 proof(induct "length xs" arbitrary: xs ys, simp add: bl2nat.simps)
       
  4467   fix x xs ys
       
  4468   assume ind: 
       
  4469     "\<And>xs ys. x = length xs \<Longrightarrow> 
       
  4470              bl2nat (xs @ ys) 0 = bl2nat xs 0 + bl2nat ys (length xs)"
       
  4471   and h: "Suc x = length (xs::block list)"
       
  4472   have "\<exists> ks k. xs = ks @ [k]" 
       
  4473     apply(rule_tac x = "butlast xs" in exI,
       
  4474       rule_tac x = "last xs" in exI)
       
  4475     using h
       
  4476     apply(case_tac xs, auto)
       
  4477     done
       
  4478   from this obtain ks k where "xs = ks @ [k]" by blast
       
  4479   moreover hence 
       
  4480     "bl2nat (ks @ (k # ys)) 0 = bl2nat ks 0 +
       
  4481                                bl2nat (k # ys) (length ks)"
       
  4482     apply(rule_tac ind) using h by simp
       
  4483   ultimately show "bl2nat (xs @ ys) 0 = 
       
  4484                   bl2nat xs 0 + bl2nat ys (length xs)"
       
  4485     apply(case_tac k, simp_all add: bl2nat.simps)
       
  4486     apply(simp_all only: bl2nat_cons_bk bl2nat_cons_oc)
       
  4487     done
       
  4488 qed
       
  4489 
       
  4490 lemma bl2nat_exp:  "n \<noteq> 0 \<Longrightarrow> bl2nat bl n = 2^n * bl2nat bl 0"
       
  4491 apply(induct bl)
       
  4492 apply(auto simp: bl2nat.simps)
       
  4493 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double)
       
  4494 done
       
  4495 
       
  4496 lemma nat_minus_eq: "\<lbrakk>a = b; c = d\<rbrakk> \<Longrightarrow> a - c = b - d"
       
  4497 by auto
       
  4498 
       
  4499 lemma tape_of_nat_list_butlast_last:
       
  4500   "ys \<noteq> [] \<Longrightarrow> <ys @ [y]> = <ys> @ Bk # Oc\<^bsup>Suc y\<^esup>"
       
  4501 apply(induct ys, simp, simp)
       
  4502 apply(case_tac "ys = []", simp add: tape_of_nl_abv 
       
  4503                                     tape_of_nat_list.simps)
       
  4504 apply(simp)
       
  4505 done
       
  4506 
       
  4507 lemma listsum2_append:
       
  4508   "\<lbrakk>n \<le> length xs\<rbrakk> \<Longrightarrow> listsum2 (xs @ ys) n = listsum2 xs n"
       
  4509 apply(induct n)
       
  4510 apply(auto simp: listsum2.simps nth_append)
       
  4511 done
       
  4512 
       
  4513 lemma strt'_append:  
       
  4514   "\<lbrakk>n \<le> length xs\<rbrakk> \<Longrightarrow> strt' xs n = strt' (xs @ ys) n"
       
  4515 proof(induct n arbitrary: xs ys)
       
  4516   fix xs ys
       
  4517   show "strt' xs 0 = strt' (xs @ ys) 0" by(simp add: strt'.simps)
       
  4518 next
       
  4519   fix n xs ys
       
  4520   assume ind: 
       
  4521     "\<And> xs ys. n \<le> length xs \<Longrightarrow> strt' xs n = strt' (xs @ ys) n"
       
  4522     and h: "Suc n \<le> length (xs::nat list)"
       
  4523   show "strt' xs (Suc n) = strt' (xs @ ys) (Suc n)"
       
  4524     using ind[of xs ys] h
       
  4525     apply(simp add: strt'.simps nth_append listsum2_append)
       
  4526     done
       
  4527 qed
       
  4528     
       
  4529 lemma length_listsum2_eq: 
       
  4530   "\<lbrakk>length (ys::nat list) = k\<rbrakk>
       
  4531        \<Longrightarrow> length (<ys>) = listsum2 (map Suc ys) k + k - 1"
       
  4532 apply(induct k arbitrary: ys, simp_all add: listsum2.simps)
       
  4533 apply(subgoal_tac "\<exists> xs x. ys = xs @ [x]", auto)
       
  4534 proof -
       
  4535   fix xs x
       
  4536   assume ind: "\<And>ys. length ys = length xs \<Longrightarrow> length (<ys>) 
       
  4537     = listsum2 (map Suc ys) (length xs) + 
       
  4538       length (xs::nat list) - Suc 0"
       
  4539   have "length (<xs>) 
       
  4540     = listsum2 (map Suc xs) (length xs) + length xs - Suc 0"
       
  4541     apply(rule_tac ind, simp)
       
  4542     done
       
  4543   thus "length (<xs @ [x]>) =
       
  4544     Suc (listsum2 (map Suc xs @ [Suc x]) (length xs) + x + length xs)"
       
  4545     apply(case_tac "xs = []")
       
  4546     apply(simp add: tape_of_nl_abv listsum2.simps 
       
  4547       tape_of_nat_list.simps)
       
  4548     apply(simp add: tape_of_nat_list_butlast_last)
       
  4549     using listsum2_append[of "length xs" "map Suc xs" "[Suc x]"]
       
  4550     apply(simp)
       
  4551     done
       
  4552 next
       
  4553   fix k ys
       
  4554   assume "length ys = Suc k" 
       
  4555   thus "\<exists>xs x. ys = xs @ [x]"
       
  4556     apply(rule_tac x = "butlast ys" in exI, 
       
  4557           rule_tac x = "last ys" in exI)
       
  4558     apply(case_tac ys, auto)
       
  4559     done
       
  4560 qed  
       
  4561 
       
  4562 lemma tape_of_nat_list_length: 
       
  4563       "length (<(ys::nat list)>) = 
       
  4564               listsum2 (map Suc ys) (length ys) + length ys - 1"
       
  4565   using length_listsum2_eq[of ys "length ys"]
       
  4566   apply(simp)
       
  4567   done
       
  4568 
       
  4569 
       
  4570 
       
  4571 lemma [simp]:
       
  4572  "trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp 0) = 
       
  4573     rec_exec rec_conf [code tp, bl2wc (<lm>), 0]"
       
  4574 apply(simp add: steps.simps rec_exec.simps conf_lemma  conf.simps 
       
  4575                 inpt.simps trpl_code.simps bl2wc.simps)
       
  4576 done
       
  4577 
       
  4578 text {*
       
  4579   The following lemma relates the multi-step interpreter function @{text "rec_conf"}
       
  4580   with the multi-step execution of TMs.
       
  4581   *}
       
  4582 lemma rec_t_eq_steps:
       
  4583   "turing_basic.t_correct tp \<Longrightarrow>
       
  4584   trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp) = 
       
  4585   rec_exec rec_conf [code tp, bl2wc (<lm>), stp]"
       
  4586 proof(induct stp)
       
  4587   case 0 thus "?case" by(simp)
       
  4588 next
       
  4589   case (Suc n) thus "?case"
       
  4590   proof -
       
  4591     assume ind: 
       
  4592       "t_correct tp \<Longrightarrow> trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp n) 
       
  4593       = rec_exec rec_conf [code tp, bl2wc (<lm>), n]"
       
  4594       and h: "t_correct tp"
       
  4595     show 
       
  4596       "trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp (Suc n)) =
       
  4597       rec_exec rec_conf [code tp, bl2wc (<lm>), Suc n]"
       
  4598     proof(case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp  n", 
       
  4599         simp only: tstep_red conf_lemma conf.simps)
       
  4600       fix a b c
       
  4601       assume g: "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp n = (a, b, c) "
       
  4602       hence "conf (code tp) (bl2wc (<lm>)) n= trpl_code (a, b, c)"
       
  4603         using ind h
       
  4604         apply(simp add: conf_lemma)
       
  4605         done
       
  4606       moreover hence 
       
  4607         "trpl_code (tstep (a, b, c) tp) = 
       
  4608         rec_exec rec_newconf [code tp, trpl_code (a, b, c)]"
       
  4609         thm rec_t_eq_step
       
  4610         apply(rule_tac rec_t_eq_step)
       
  4611         using h g
       
  4612         apply(simp add: s_keep)
       
  4613         done
       
  4614       ultimately show 
       
  4615         "trpl_code (tstep (a, b, c) tp) =
       
  4616             newconf (code tp) (conf (code tp) (bl2wc (<lm>)) n)"
       
  4617         by(simp add: newconf_lemma)
       
  4618     qed
       
  4619   qed
       
  4620 qed
       
  4621 
       
  4622 lemma [simp]: "bl2wc (Bk\<^bsup>m\<^esup>) = 0"
       
  4623 apply(induct m)
       
  4624 apply(simp, simp)
       
  4625 done
       
  4626 
       
  4627 lemma [simp]: "bl2wc (Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>) = bl2wc (Oc\<^bsup>rs\<^esup>)"
       
  4628 apply(induct rs, simp, 
       
  4629   simp add: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4630 done
       
  4631 
       
  4632 lemma lg_power: "x > Suc 0 \<Longrightarrow> lg (x ^ rs) x = rs"
       
  4633 proof(simp add: lg.simps, auto)
       
  4634   fix xa
       
  4635   assume h: "Suc 0 < x"
       
  4636   show "Max {ya. ya \<le> x ^ rs \<and> lgR [x ^ rs, x, ya]} = rs"
       
  4637     apply(rule_tac Max_eqI, simp_all add: lgR.simps)
       
  4638     apply(simp add: h)
       
  4639     using x_less_exp[of x rs] h
       
  4640     apply(simp)
       
  4641     done
       
  4642 next
       
  4643   assume "\<not> Suc 0 < x ^ rs" "Suc 0 < x" 
       
  4644   thus "rs = 0"
       
  4645     apply(case_tac "x ^ rs", simp, simp)
       
  4646     done
       
  4647 next
       
  4648   assume "Suc 0 < x" "\<forall>xa. \<not> lgR [x ^ rs, x, xa]"
       
  4649   thus "rs = 0"
       
  4650     apply(simp only:lgR.simps)
       
  4651     apply(erule_tac x = rs in allE, simp)
       
  4652     done
       
  4653 qed    
       
  4654 
       
  4655 text {*
       
  4656   The following lemma relates execution of TMs with 
       
  4657   the multi-step interpreter function @{text "rec_nonstop"}. Note,
       
  4658   @{text "rec_nonstop"} is constructed using @{text "rec_conf"}.
       
  4659   *}
       
  4660 lemma nonstop_t_eq: 
       
  4661   "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>); 
       
  4662   turing_basic.t_correct tp; 
       
  4663   rs > 0\<rbrakk> 
       
  4664   \<Longrightarrow> rec_exec rec_nonstop [code tp, bl2wc (<lm>), stp] = 0"
       
  4665 proof(simp add: nonstop_lemma nonstop.simps nstd.simps)
       
  4666   assume h: "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4667   and tc_t: "turing_basic.t_correct tp" "rs > 0"
       
  4668   have g: "rec_exec rec_conf [code tp,  bl2wc (<lm>), stp] =
       
  4669                                         trpl_code (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>)"
       
  4670     using rec_t_eq_steps[of tp l lm stp] tc_t h
       
  4671     by(simp)
       
  4672   thus "\<not> NSTD (conf (code tp) (bl2wc (<lm>)) stp)" 
       
  4673   proof(auto simp: NSTD.simps)
       
  4674     show "stat (conf (code tp) (bl2wc (<lm>)) stp) = 0"
       
  4675       using g
       
  4676       by(auto simp: conf_lemma trpl_code.simps)
       
  4677   next
       
  4678     show "left (conf (code tp) (bl2wc (<lm>)) stp) = 0"
       
  4679       using g
       
  4680       by(simp add: conf_lemma trpl_code.simps)
       
  4681   next
       
  4682     show "rght (conf (code tp) (bl2wc (<lm>)) stp) = 
       
  4683            2 ^ lg (Suc (rght (conf (code tp) (bl2wc (<lm>)) stp))) 2 - Suc 0"
       
  4684     using g h
       
  4685     proof(simp add: conf_lemma trpl_code.simps)
       
  4686       have "2 ^ lg (Suc (bl2wc (Oc\<^bsup>rs\<^esup>))) 2 = Suc (bl2wc (Oc\<^bsup>rs\<^esup>))"
       
  4687         apply(simp add: bl2wc.simps lg_power)
       
  4688         done
       
  4689       thus "bl2wc (Oc\<^bsup>rs\<^esup>) = 2 ^ lg (Suc (bl2wc (Oc\<^bsup>rs\<^esup>))) 2 - Suc 0"
       
  4690         apply(simp)
       
  4691         done
       
  4692     qed
       
  4693   next
       
  4694     show "0 < rght (conf (code tp) (bl2wc (<lm>)) stp)"
       
  4695       using g h tc_t
       
  4696       apply(simp add: conf_lemma trpl_code.simps bl2wc.simps
       
  4697                       bl2nat.simps)
       
  4698       apply(case_tac rs, simp, simp add: bl2nat.simps)
       
  4699       done
       
  4700   qed
       
  4701 qed
       
  4702 
       
  4703 lemma [simp]: "actn m 0 r = 4"
       
  4704 by(simp add: actn.simps)
       
  4705 
       
  4706 lemma [simp]: "newstat m 0 r = 0"
       
  4707 by(simp add: newstat.simps)
       
  4708  
       
  4709 declare exp_def[simp del]
       
  4710 
       
  4711 lemma halt_least_step: 
       
  4712   "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs \<^esup> @ Bk\<^bsup>n\<^esup>); 
       
  4713     turing_basic.t_correct tp; 
       
  4714     0<rs\<rbrakk> \<Longrightarrow>
       
  4715     \<exists> stp. (nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and>
       
  4716        (\<forall> stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp'))"
       
  4717 proof(induct stp, simp add: steps.simps, simp)
       
  4718   fix stp
       
  4719   assume ind: 
       
  4720     "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>) \<Longrightarrow> 
       
  4721     \<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and> 
       
  4722           (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')"
       
  4723   and h: 
       
  4724     "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp (Suc stp) = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4725     "turing_basic.t_correct tp" 
       
  4726     "0 < rs"
       
  4727   from h show 
       
  4728     "\<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 
       
  4729     \<and> (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')"
       
  4730   proof(simp add: tstep_red, 
       
  4731       case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp", simp, 
       
  4732        case_tac a, simp add: tstep_0)
       
  4733     assume "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4734     thus "\<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and> 
       
  4735       (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')"
       
  4736       apply(erule_tac ind)
       
  4737       done
       
  4738   next
       
  4739     fix a b c nat
       
  4740     assume "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (a, b, c)"
       
  4741       "a = Suc nat"
       
  4742     thus "\<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and> 
       
  4743       (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')"
       
  4744       using h
       
  4745       apply(rule_tac x = "Suc stp" in exI, auto)
       
  4746       apply(drule_tac  nonstop_t_eq, simp_all add: nonstop_lemma)
       
  4747     proof -
       
  4748       fix stp'
       
  4749       assume g:"steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (Suc nat, b, c)" 
       
  4750         "nonstop (code tp) (bl2wc (<lm>)) stp' = 0"
       
  4751       thus  "Suc stp \<le> stp'"
       
  4752       proof(case_tac "Suc stp \<le> stp'", simp, simp)
       
  4753         assume "\<not> Suc stp \<le> stp'"
       
  4754         hence "stp' \<le> stp" by simp
       
  4755         hence "\<not> isS0 (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp')"
       
  4756           using g
       
  4757           apply(case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp'",auto,
       
  4758             simp add: isS0_def)
       
  4759           apply(subgoal_tac "\<exists> n. stp = stp' + n", 
       
  4760             auto simp: steps_add steps_0)
       
  4761           apply(rule_tac x = "stp - stp'"  in exI, simp)
       
  4762           done         
       
  4763         hence "nonstop (code tp) (bl2wc (<lm>)) stp' = 1"
       
  4764         proof(case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp'",
       
  4765             simp add: isS0_def nonstop.simps)
       
  4766           fix a b c
       
  4767           assume k: 
       
  4768             "0 < a" "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp' = (a, b, c)"
       
  4769           thus " NSTD (conf (code tp) (bl2wc (<lm>)) stp')"
       
  4770             using rec_t_eq_steps[of tp l lm stp'] h
       
  4771           proof(simp add: conf_lemma)
       
  4772             assume "trpl_code (a, b, c) = conf (code tp) (bl2wc (<lm>)) stp'"
       
  4773             moreover have "NSTD (trpl_code (a, b, c))"
       
  4774               using k
       
  4775               apply(auto simp: trpl_code.simps NSTD.simps)
       
  4776               done
       
  4777             ultimately show "NSTD (conf (code tp) (bl2wc (<lm>)) stp')" by simp
       
  4778           qed
       
  4779         qed
       
  4780         thus "False" using g by simp
       
  4781       qed
       
  4782     qed
       
  4783   qed
       
  4784 qed    
       
  4785 
       
  4786 (*
       
  4787 lemma halt_steps_ex: 
       
  4788   "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>); 
       
  4789   lm \<noteq> []; turing_basic.t_correct tp; 0<rs\<rbrakk> \<Longrightarrow>
       
  4790   \<exists> t. rec_calc_rel (rec_halt (length lm)) (code tp # lm) t"
       
  4791 apply(drule_tac halt_least_step, auto)
       
  4792 apply(rule_tac x = stp in exI)
       
  4793 apply(simp add: halt_lemma nonstop_lemma)
       
  4794 apply(auto)
       
  4795 done*)
       
  4796 thm loR.simps
       
  4797 
       
  4798 lemma conf_trpl_ex: "\<exists> p q r. conf m (bl2wc (<lm>)) stp = trpl p q r"
       
  4799 apply(induct stp, auto simp: conf.simps inpt.simps trpl.simps 
       
  4800   newconf.simps)
       
  4801 apply(rule_tac x = 0 in exI, rule_tac x = 1 in exI, 
       
  4802   rule_tac x = "bl2wc (<lm>)" in exI)
       
  4803 apply(simp)
       
  4804 done
       
  4805   
       
  4806 lemma nonstop_rgt_ex: 
       
  4807   "nonstop m (bl2wc (<lm>)) stpa = 0 \<Longrightarrow> \<exists> r. conf m (bl2wc (<lm>)) stpa = trpl 0 0 r"
       
  4808 apply(auto simp: nonstop.simps NSTD.simps split: if_splits)
       
  4809 using conf_trpl_ex[of m lm stpa]
       
  4810 apply(auto)
       
  4811 done
       
  4812 
       
  4813 lemma [elim]: "x > Suc 0 \<Longrightarrow> Max {u. x ^ u dvd x ^ r} = r"
       
  4814 proof(rule_tac Max_eqI)
       
  4815   assume "x > Suc 0"
       
  4816   thus "finite {u. x ^ u dvd x ^ r}"
       
  4817     apply(rule_tac finite_power_dvd, auto)
       
  4818     done
       
  4819 next
       
  4820   fix y 
       
  4821   assume "Suc 0 < x" "y \<in> {u. x ^ u dvd x ^ r}"
       
  4822   thus "y \<le> r"
       
  4823     apply(case_tac "y\<le> r", simp)
       
  4824     apply(subgoal_tac "\<exists> d. y = r + d")
       
  4825     apply(auto simp: power_add)
       
  4826     apply(rule_tac x = "y - r" in exI, simp)
       
  4827     done
       
  4828 next
       
  4829   show "r \<in> {u. x ^ u dvd x ^ r}" by simp
       
  4830 qed  
       
  4831 
       
  4832 lemma lo_power: "x > Suc 0 \<Longrightarrow> lo (x ^ r) x = r"
       
  4833 apply(auto simp: lo.simps loR.simps mod_dvd_simp)
       
  4834 apply(case_tac "x^r", simp_all)
       
  4835 done
       
  4836 
       
  4837 lemma lo_rgt: "lo (trpl 0 0 r) (Pi 2) = r"
       
  4838 apply(simp add: trpl.simps lo_power)
       
  4839 done
       
  4840 
       
  4841 lemma conf_keep: 
       
  4842   "conf m lm stp = trpl 0 0 r  \<Longrightarrow>
       
  4843   conf m lm (stp + n) = trpl 0 0 r"
       
  4844 apply(induct n)
       
  4845 apply(auto simp: conf.simps  newconf.simps newleft.simps 
       
  4846   newrght.simps rght.simps lo_rgt)
       
  4847 done
       
  4848 
       
  4849 lemma halt_state_keep_steps_add:
       
  4850   "\<lbrakk>nonstop m (bl2wc (<lm>)) stpa = 0\<rbrakk> \<Longrightarrow> 
       
  4851   conf m (bl2wc (<lm>)) stpa = conf m (bl2wc (<lm>)) (stpa + n)"
       
  4852 apply(drule_tac nonstop_rgt_ex, auto simp: conf_keep)
       
  4853 done
       
  4854 
       
  4855 lemma halt_state_keep: 
       
  4856   "\<lbrakk>nonstop m (bl2wc (<lm>)) stpa = 0; nonstop m (bl2wc (<lm>)) stpb = 0\<rbrakk> \<Longrightarrow>
       
  4857   conf m (bl2wc (<lm>)) stpa = conf m (bl2wc (<lm>)) stpb"
       
  4858 apply(case_tac "stpa > stpb")
       
  4859 using halt_state_keep_steps_add[of m lm stpb "stpa - stpb"] 
       
  4860 apply simp
       
  4861 using halt_state_keep_steps_add[of m lm stpa "stpb - stpa"]
       
  4862 apply(simp)
       
  4863 done
       
  4864 
       
  4865 thm halt_lemma
       
  4866 
       
  4867 text {*
       
  4868   The correntess of @{text "rec_F"} which relates the interpreter function @{text "rec_F"} with the
       
  4869   execution of of TMs.
       
  4870   *}
       
  4871 lemma F_t_halt_eq: 
       
  4872   "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>); 
       
  4873     turing_basic.t_correct tp; 
       
  4874     0<rs\<rbrakk>
       
  4875    \<Longrightarrow> rec_calc_rel rec_F [code tp, (bl2wc (<lm>))] (rs - Suc 0)"
       
  4876 apply(frule_tac halt_least_step, auto)
       
  4877 apply(frule_tac  nonstop_t_eq, auto simp: nonstop_lemma)
       
  4878 using rec_t_eq_steps[of tp l lm stp]
       
  4879 apply(simp add: conf_lemma)
       
  4880 proof -
       
  4881   fix stpa
       
  4882   assume h: 
       
  4883     "nonstop (code tp) (bl2wc (<lm>)) stpa = 0" 
       
  4884     "\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stpa \<le> stp'" 
       
  4885     "nonstop (code tp) (bl2wc (<lm>)) stp = 0" 
       
  4886     "trpl_code (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>) = conf (code tp) (bl2wc (<lm>)) stp"
       
  4887     "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4888   hence g1: "conf (code tp) (bl2wc (<lm>)) stpa = trpl_code (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4889     using halt_state_keep[of "code tp" lm stpa stp]
       
  4890     by(simp)
       
  4891   moreover have g2:
       
  4892     "rec_calc_rel rec_halt [code tp, (bl2wc (<lm>))] stpa"
       
  4893     using h
       
  4894     apply(simp add: halt_lemma nonstop_lemma, auto)
       
  4895     done
       
  4896   show  
       
  4897     "rec_calc_rel rec_F [code tp, (bl2wc (<lm>))] (rs - Suc 0)"
       
  4898   proof -
       
  4899     have 
       
  4900       "rec_calc_rel rec_F [code tp, (bl2wc (<lm>))] 
       
  4901                          (valu (rght (conf (code tp) (bl2wc (<lm>)) stpa)))"
       
  4902       apply(rule F_lemma) using g2 h by auto
       
  4903     moreover have 
       
  4904       "valu (rght (conf (code tp) (bl2wc (<lm>)) stpa)) = rs - Suc 0" 
       
  4905       using g1 
       
  4906       apply(simp add: valu.simps trpl_code.simps 
       
  4907         bl2wc.simps  bl2nat_append lg_power)
       
  4908       done
       
  4909     ultimately show "?thesis" by simp
       
  4910   qed
       
  4911 qed
       
  4912 
       
  4913 
       
  4914 end