thys/UF.thy
changeset 288 a9003e6d0463
parent 250 745547bdc1c7
child 289 4e50ff177348
equal deleted inserted replaced
287:d5a0e25c4742 288:a9003e6d0463
     1 (* Title: thys/UF.thy
     1 (* Title: thys/UF.thy
     2    Author: Jian Xu, Xingyuan Zhang, and Christian Urban
     2    Author: Jian Xu, Xingyuan Zhang, and Christian Urban
     3 *)
     3 *)
     4 
     4 
     5 header {* Construction of a Universal Function *}
     5 chapter {* Construction of a Universal Function *}
     6 
     6 
     7 theory UF
     7 theory UF
     8 imports Rec_Def GCD Abacus
     8 imports Rec_Def HOL.GCD Abacus
     9 begin
     9 begin
    10 
    10 
    11 text {*
    11 text {*
    12   This theory file constructs the Universal Function @{text "rec_F"}, which is the UTM defined
    12   This theory file constructs the Universal Function @{text "rec_F"}, which is the UTM defined
    13   in terms of recursive functions. This @{text "rec_F"} is essentially an 
    13   in terms of recursive functions. This @{text "rec_F"} is essentially an 
   287 
   287 
   288 declare rec_exec.simps[simp del] get_fstn_args.simps[simp del]
   288 declare rec_exec.simps[simp del] get_fstn_args.simps[simp del]
   289         arity.simps[simp del] Sigma.simps[simp del]
   289         arity.simps[simp del] Sigma.simps[simp del]
   290         rec_sigma.simps[simp del]
   290         rec_sigma.simps[simp del]
   291 
   291 
   292 lemma [simp]: "arity z = 1"
       
   293  by(simp add: arity.simps)
       
   294 
       
   295 lemma rec_pr_0_simp_rewrite: "
   292 lemma rec_pr_0_simp_rewrite: "
   296   rec_exec (Pr n f g) (xs @ [0]) = rec_exec f xs"
   293   rec_exec (Pr n f g) (xs @ [0]) = rec_exec f xs"
   297 by(simp add: rec_exec.simps)
   294 by(simp add: rec_exec.simps)
   298 
   295 
   299 lemma rec_pr_0_simp_rewrite_single_param: "
   296 lemma rec_pr_0_simp_rewrite_single_param: "
   339   case (Suc n) thus "?case"
   336   case (Suc n) thus "?case"
   340     by(simp add: get_fstn_args.simps rec_exec.simps 
   337     by(simp add: get_fstn_args.simps rec_exec.simps 
   341              take_Suc_conv_app_nth)
   338              take_Suc_conv_app_nth)
   342 qed
   339 qed
   343     
   340     
   344 lemma [simp]: "primerec f n \<Longrightarrow> arity f = n"
   341 lemma arity_primerec[simp]: "primerec f n \<Longrightarrow> arity f = n"
   345   apply(case_tac f)
   342   apply(case_tac f)
   346   apply(auto simp: arity.simps )
   343   apply(auto simp: arity.simps )
   347   apply(erule_tac prime_mn_reverse)
   344   apply(erule_tac prime_mn_reverse)
   348   done
   345   done
   349 
   346 
   525 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<le> x")
   522 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<le> x")
   526 apply(erule_tac order_trans, simp)
   523 apply(erule_tac order_trans, simp)
   527 apply(rule_tac Min_le, auto)
   524 apply(rule_tac Min_le, auto)
   528 done
   525 done
   529 
   526 
   530 lemma [simp]: "{x. x \<le> Suc w \<and> Rr (xs @ [x])}
   527 lemma expand_conj_in_set: "{x. x \<le> Suc w \<and> Rr (xs @ [x])}
   531     = (if Rr (xs @ [Suc w]) then insert (Suc w) 
   528     = (if Rr (xs @ [Suc w]) then insert (Suc w) 
   532                               {x. x \<le> w \<and> Rr (xs @ [x])}
   529                               {x. x \<le> w \<and> Rr (xs @ [x])}
   533       else {x. x \<le> w \<and> Rr (xs @ [x])})"
   530       else {x. x \<le> w \<and> Rr (xs @ [x])})"
   534 by(auto, case_tac "x = Suc w", auto)
   531 by(auto, case_tac "x = Suc w", auto)
   535 
   532 
   536 lemma [simp]: "Minr Rr xs w \<le> w \<Longrightarrow> Minr Rr xs (Suc w) = Minr Rr xs w"
   533 lemma Minr_strip_Suc[simp]: "Minr Rr xs w \<le> w \<Longrightarrow> Minr Rr xs (Suc w) = Minr Rr xs w"
   537 apply(simp add: Minr.simps, auto)
   534 by(cases "\<forall>x\<le>w. \<not> Rr (xs @ [x])",auto simp add: Minr.simps expand_conj_in_set)
   538 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
   535 
   539 done
   536 lemma x_empty_set[simp]: "\<forall>x\<le>w. \<not> Rr (xs @ [x]) \<Longrightarrow>  
   540 
       
   541 lemma [simp]: "\<forall>x\<le>w. \<not> Rr (xs @ [x]) \<Longrightarrow>  
       
   542                            {x. x \<le> w \<and> Rr (xs @ [x])} = {} "
   537                            {x. x \<le> w \<and> Rr (xs @ [x])} = {} "
   543 by auto
   538 by auto
   544 
   539 
   545 lemma [simp]: "\<lbrakk>Minr Rr xs w = Suc w; Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> 
   540 lemma Minr_is_Suc[simp]: "\<lbrakk>Minr Rr xs w = Suc w; Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> 
   546                                        Minr Rr xs (Suc w) = Suc w"
   541                                        Minr Rr xs (Suc w) = Suc w"
   547 apply(simp add: Minr.simps)
   542 apply(simp add: Minr.simps expand_conj_in_set)
   548 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
   543 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
   549 done
   544 done
   550  
   545  
   551 lemma [simp]: "\<lbrakk>Minr Rr xs w = Suc w; \<not> Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> 
   546 lemma Minr_is_Suc_Suc[simp]: "\<lbrakk>Minr Rr xs w = Suc w; \<not> Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> 
   552                                    Minr Rr xs (Suc w) = Suc (Suc w)"
   547                                    Minr Rr xs (Suc w) = Suc (Suc w)"
   553 apply(simp add: Minr.simps)
   548 apply(simp add: Minr.simps expand_conj_in_set)
   554 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
   549 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto)
   555 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<in> 
   550 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<in> 
   556                                 {x. x \<le> w \<and> Rr (xs @ [x])}", simp)
   551                                 {x. x \<le> w \<and> Rr (xs @ [x])}", simp)
   557 apply(rule_tac Min_in, auto)
   552 apply(rule_tac Min_in, auto)
   558 done
   553 done
   610 lemma min_Suc_Suc[simp]: "min (Suc (Suc x)) x = x"
   605 lemma min_Suc_Suc[simp]: "min (Suc (Suc x)) x = x"
   611  by auto
   606  by auto
   612 
   607 
   613 declare numeral_3_eq_3[simp]
   608 declare numeral_3_eq_3[simp]
   614 
   609 
   615 lemma [intro]: "primerec rec_pred (Suc 0)"
   610 lemma primerec_rec_pred_1[intro]: "primerec rec_pred (Suc 0)"
   616 apply(simp add: rec_pred_def)
   611 apply(simp add: rec_pred_def)
   617 apply(rule_tac prime_cn, auto)
   612 apply(rule_tac prime_cn, auto)
   618 apply(case_tac i, auto intro: prime_id)
   613 apply(case_tac i, auto intro: prime_id)
   619 done
   614 done
   620 
   615 
   621 lemma [intro]: "primerec rec_minus (Suc (Suc 0))"
   616 lemma primerec_rec_minus_2[intro]: "primerec rec_minus (Suc (Suc 0))"
   622   apply(auto simp: rec_minus_def)
   617   apply(auto simp: rec_minus_def)
   623   done
   618   done
   624 
   619 
   625 lemma [intro]: "primerec (constn n) (Suc 0)"
   620 lemma primerec_constn_1[intro]: "primerec (constn n) (Suc 0)"
   626   apply(induct n)
   621   apply(induct n)
   627   apply(auto simp: constn.simps intro: prime_z prime_cn prime_s)
   622   apply(auto simp: constn.simps intro: prime_z prime_cn prime_s)
   628   done
   623   done
   629 
   624 
   630 lemma [intro]: "primerec rec_sg (Suc 0)" 
   625 lemma primerec_rec_sg_1[intro]: "primerec rec_sg (Suc 0)" 
   631   apply(simp add: rec_sg_def)
   626   apply(simp add: rec_sg_def)
   632   apply(rule_tac k = "Suc (Suc 0)" in prime_cn, auto)
   627   apply(rule_tac k = "Suc (Suc 0)" in prime_cn, auto)
   633   apply(case_tac i, auto)
   628   apply(case_tac i, auto)
   634   apply(case_tac ia, auto intro: prime_id)
   629   apply(case_tac ia, auto intro: prime_id)
   635   done
   630   done
   636 
   631 
   637 lemma [simp]: "length (get_fstn_args m n) = n"
   632 lemma primerec_getpren[elim]: "\<lbrakk>i < n; n \<le> m\<rbrakk> \<Longrightarrow> primerec (get_fstn_args m n ! i) m"
   638   apply(induct n)
       
   639   apply(auto simp: get_fstn_args.simps)
       
   640   done
       
   641 
       
   642 lemma  primerec_getpren[elim]: "\<lbrakk>i < n; n \<le> m\<rbrakk> \<Longrightarrow> primerec (get_fstn_args m n ! i) m"
       
   643 apply(induct n, auto simp: get_fstn_args.simps)
   633 apply(induct n, auto simp: get_fstn_args.simps)
   644 apply(case_tac "i = n", auto simp: nth_append intro: prime_id)
   634 apply(case_tac "i = n", auto simp: nth_append intro: prime_id)
   645 done
   635 done
   646 
   636 
   647 lemma [intro]: "primerec rec_add (Suc (Suc 0))"
   637 lemma primerec_rec_add_2[intro]: "primerec rec_add (Suc (Suc 0))"
   648 apply(simp add: rec_add_def)
   638 apply(simp add: rec_add_def)
   649 apply(rule_tac prime_pr, auto)
   639 apply(rule_tac prime_pr, auto)
   650 done
   640 done
   651 
   641 
   652 lemma [intro]:"primerec rec_mult (Suc (Suc 0))"
   642 lemma primerec_rec_mult_2[intro]:"primerec rec_mult (Suc (Suc 0))"
   653 apply(simp add: rec_mult_def )
   643 apply(simp add: rec_mult_def )
   654 apply(rule_tac prime_pr, auto intro: prime_z)
   644 apply(rule_tac prime_pr, auto intro: prime_z)
   655 apply(case_tac i, auto intro: prime_id)
   645 apply(case_tac i, auto intro: prime_id)
   656 done  
   646 done  
   657 
   647 
   658 lemma [elim]: "\<lbrakk>primerec rf n; n \<ge> Suc (Suc 0)\<rbrakk>   \<Longrightarrow> 
   648 lemma primerec_ge_2_elim[elim]: "\<lbrakk>primerec rf n; n \<ge> Suc (Suc 0)\<rbrakk>   \<Longrightarrow> 
   659                         primerec (rec_accum rf) n"
   649                         primerec (rec_accum rf) n"
   660 apply(auto simp: rec_accum.simps)
   650 apply(auto simp: rec_accum.simps)
   661 apply(simp add: nth_append, auto)
   651 apply(simp add: nth_append, auto)
   662 apply(case_tac i, auto intro: prime_id)
   652 apply(case_tac i, auto intro: prime_id)
   663 apply(auto simp: nth_append)
   653 apply(auto simp: nth_append)
   668                                  primerec (rec_all rt rf) n"
   658                                  primerec (rec_all rt rf) n"
   669   apply(simp add: rec_all.simps, auto)
   659   apply(simp add: rec_all.simps, auto)
   670   apply(auto, simp add: nth_append, auto)
   660   apply(auto, simp add: nth_append, auto)
   671   done
   661   done
   672 
   662 
   673 lemma [simp]: "Rr (xs @ [0]) \<Longrightarrow> 
   663 lemma min_P0[simp]: "Rr (xs @ [0]) \<Longrightarrow> 
   674                    Min {x. x = (0::nat) \<and> Rr (xs @ [x])} = 0"
   664                    Min {x. x = (0::nat) \<and> Rr (xs @ [x])} = 0"
   675 by(rule_tac Min_eqI, simp, simp, simp)
   665 by(rule_tac Min_eqI, simp, simp, simp)
   676 
   666 
   677 lemma [intro]: "primerec rec_not (Suc 0)"
   667 lemma primerec_rec_not_1[intro]: "primerec rec_not (Suc 0)"
   678 apply(simp add: rec_not_def)
   668 apply(simp add: rec_not_def)
   679 apply(rule prime_cn, auto)
   669 apply(rule prime_cn, auto)
   680 apply(case_tac i, auto intro: prime_id)
   670 apply(case_tac i, auto intro: prime_id)
   681 done
   671 done
   682 
   672 
   823                   in Cn vl (rec_sigma Qf) (get_fstn_args vl vl @
   813                   in Cn vl (rec_sigma Qf) (get_fstn_args vl vl @
   824                                                          [id vl (vl - 1)]))"
   814                                                          [id vl (vl - 1)]))"
   825 
   815 
   826 declare rec_maxr.simps[simp del] Maxr.simps[simp del] 
   816 declare rec_maxr.simps[simp del] Maxr.simps[simp del] 
   827 declare le_lemma[simp]
   817 declare le_lemma[simp]
   828 lemma [simp]: "(min (Suc (Suc (Suc (x)))) (x)) = x"
   818 lemma min_with_suc3[simp]: "(min (Suc (Suc (Suc (x)))) (x)) = x"
   829 by simp
   819 by simp
   830 
   820 
   831 declare numeral_2_eq_2[simp]
   821 declare numeral_2_eq_2[simp]
   832 
   822 
   833 lemma [intro]: "primerec rec_disj (Suc (Suc 0))"
   823 lemma primerec_rec_disj_2[intro]: "primerec rec_disj (Suc (Suc 0))"
   834   apply(simp add: rec_disj_def, auto)
   824   apply(simp add: rec_disj_def, auto)
   835   apply(auto)
   825   apply(auto)
   836   apply(case_tac ia, auto intro: prime_id)
   826   apply(case_tac ia, auto intro: prime_id)
   837   done
   827   done
   838 
   828 
   839 lemma [intro]: "primerec rec_less (Suc (Suc 0))"
   829 lemma primerec_rec_less_2[intro]: "primerec rec_less (Suc (Suc 0))"
   840   apply(simp add: rec_less_def, auto)
   830   apply(simp add: rec_less_def, auto)
   841   apply(auto)
   831   apply(auto)
   842   apply(case_tac ia , auto intro: prime_id)
   832   apply(case_tac ia , auto intro: prime_id)
   843   done
   833   done
   844 
   834 
   845 lemma [intro]: "primerec rec_eq (Suc (Suc 0))"
   835 lemma primerec_rec_eq_2[intro]: "primerec rec_eq (Suc (Suc 0))"
   846   apply(simp add: rec_eq_def)
   836   apply(simp add: rec_eq_def)
   847   apply(rule_tac prime_cn, auto)
   837   apply(rule_tac prime_cn, auto)
   848   apply(case_tac i, auto)
   838   apply(case_tac i, auto)
   849   apply(case_tac ia, auto)
   839   apply(case_tac ia, auto)
   850   apply(case_tac [!] i, auto intro: prime_id)
   840   apply(case_tac [!] i, auto intro: prime_id)
   851   done
   841   done
   852 
   842 
   853 lemma [intro]: "primerec rec_le (Suc (Suc 0))"
   843 lemma primerec_rec_le_2[intro]: "primerec rec_le (Suc (Suc 0))"
   854   apply(simp add: rec_le_def)
   844   apply(simp add: rec_le_def)
   855   apply(rule_tac prime_cn, auto)
   845   apply(rule_tac prime_cn, auto)
   856   apply(case_tac i, auto)
   846   apply(case_tac i, auto)
   857   done
   847   done
   858 
   848 
   859 lemma [simp]:  
   849 lemma take_butlast_list_plus_two[simp]:  
   860   "length ys = Suc n \<Longrightarrow> (take n ys @ [ys ! n, ys ! n]) =  
   850   "length ys = Suc n \<Longrightarrow> (take n ys @ [ys ! n, ys ! n]) =  
   861                                                   ys @ [ys ! n]"
   851                                                   ys @ [ys ! n]"
   862 apply(simp)
   852 apply(simp)
   863 apply(subgoal_tac "\<exists> xs y. ys = xs @ [y]", auto)
   853 apply(subgoal_tac "\<exists> xs y. ys = xs @ [y]", auto)
   864 apply(rule_tac x = "butlast ys" in exI, rule_tac x = "last ys" in exI)
   854 apply(rule_tac x = "butlast ys" in exI, rule_tac x = "last ys" in exI)
   866 done
   856 done
   867 
   857 
   868 lemma Maxr_Suc_simp: 
   858 lemma Maxr_Suc_simp: 
   869   "Maxr Rr xs (Suc w) =(if Rr (xs @ [Suc w]) then Suc w
   859   "Maxr Rr xs (Suc w) =(if Rr (xs @ [Suc w]) then Suc w
   870      else Maxr Rr xs w)"
   860      else Maxr Rr xs w)"
   871 apply(auto simp: Maxr.simps Max.insert)
   861 apply(auto simp: Maxr.simps expand_conj_in_set)
   872 apply(rule_tac Max_eqI, auto)
   862 apply(rule_tac Max_eqI, auto)
   873 done
   863 done
   874 
   864 
   875 lemma [simp]: "min (Suc n) n = n" by simp
   865 lemma min_Suc_1[simp]: "min (Suc n) n = n" by simp
   876 
   866 
   877 lemma Sigma_0: "\<forall> i \<le> n. (f (xs @ [i]) = 0) \<Longrightarrow> 
   867 lemma Sigma_0: "\<forall> i \<le> n. (f (xs @ [i]) = 0) \<Longrightarrow> 
   878                               Sigma f (xs @ [n]) = 0"
   868                               Sigma f (xs @ [n]) = 0"
   879 apply(induct n, simp add: Sigma.simps)
   869 apply(induct n, simp add: Sigma.simps)
   880 apply(simp add: Sigma_Suc_simp_rewrite)
   870 apply(simp add: Sigma_Suc_simp_rewrite)
   881 done
   871 done
   882   
   872   
   883 lemma [elim]: "\<forall>k<Suc w. f (xs @ [k]) = Suc 0
   873 lemma Sigma_Suc[elim]: "\<forall>k<Suc w. f (xs @ [k]) = Suc 0
   884         \<Longrightarrow> Sigma f (xs @ [w]) = Suc w"
   874         \<Longrightarrow> Sigma f (xs @ [w]) = Suc w"
   885 apply(induct w)
   875 apply(induct w)
   886 apply(simp add: Sigma.simps, simp)
   876 apply(simp add: Sigma.simps, simp)
   887 apply(simp add: Sigma.simps)
   877 apply(simp add: Sigma.simps)
   888 done
   878 done
  1056 declare quo.simps[simp del]
  1046 declare quo.simps[simp del]
  1057 
  1047 
  1058 text {*
  1048 text {*
  1059   The following lemmas shows more directly the menaing of @{text "quo"}:
  1049   The following lemmas shows more directly the menaing of @{text "quo"}:
  1060   *}
  1050   *}
  1061 lemma [elim!]: "y > 0 \<Longrightarrow> quo [x, y] = x div y"
  1051 lemma quo_is_div: "y > 0 \<Longrightarrow> quo [x, y] = x div y"
  1062 proof(simp add: quo.simps Maxr.simps, auto,
  1052 proof -
  1063       rule_tac Max_eqI, simp, auto)
  1053   {
  1064   fix xa ya
  1054   fix xa ya
  1065   assume h: "y * ya \<le> x"  "y > 0"
  1055   assume h: "y * ya \<le> x"  "y > 0"
  1066   hence "(y * ya) div y \<le> x div y"
  1056   hence "(y * ya) div y \<le> x div y"
  1067     by(insert div_le_mono[of "y * ya" x y], simp)
  1057     by(insert div_le_mono[of "y * ya" x y], simp)
  1068   from this and h show "ya \<le> x div y" by simp
  1058   from this and h have "ya \<le> x div y" by simp}
  1069 next
  1059   thus ?thesis by(simp add: quo.simps Maxr.simps, auto,
  1070   fix xa
  1060       rule_tac Max_eqI, simp, auto)
  1071   show "y * (x div y) \<le> x"
       
  1072     apply(subgoal_tac "y * (x div y) + x mod y = x")
       
  1073     apply(rule_tac k = "x mod y" in add_leD1, simp)
       
  1074     apply(simp)
       
  1075     done
       
  1076 qed
  1061 qed
  1077 
  1062 
  1078 lemma [intro]: "quo [x, 0] = 0"
  1063 lemma quo_zero[intro]: "quo [x, 0] = 0"
  1079 by(simp add: quo.simps Maxr.simps)
  1064 by(simp add: quo.simps Maxr.simps)
  1080 
  1065 
  1081 lemma quo_div: "quo [x, y] = x div y"  
  1066 lemma quo_div: "quo [x, y] = x div y"  
  1082 by(case_tac "y=0", auto)
  1067 by(case_tac "y=0", auto elim!:quo_is_div)
  1083 
  1068 
  1084 text {*
  1069 text {*
  1085   @{text "rec_noteq"} is the recursive function testing whether its
  1070   @{text "rec_noteq"} is the recursive function testing whether its
  1086   two arguments are not equal.
  1071   two arguments are not equal.
  1087   *}
  1072   *}
  1118                               [id (Suc (Suc (Suc 0))) (0)]]] 
  1103                               [id (Suc (Suc (Suc 0))) (0)]]] 
  1119               in Cn (Suc (Suc 0)) (rec_maxr rR)) [id (Suc (Suc 0)) 
  1104               in Cn (Suc (Suc 0)) (rec_maxr rR)) [id (Suc (Suc 0)) 
  1120                            (0),id (Suc (Suc 0)) (Suc (0)), 
  1105                            (0),id (Suc (Suc 0)) (Suc (0)), 
  1121                                    id (Suc (Suc 0)) (0)]"
  1106                                    id (Suc (Suc 0)) (0)]"
  1122 
  1107 
  1123 lemma [intro]: "primerec rec_conj (Suc (Suc 0))"
  1108 lemma primerec_rec_conj_2[intro]: "primerec rec_conj (Suc (Suc 0))"
  1124   apply(simp add: rec_conj_def)
  1109   apply(simp add: rec_conj_def)
  1125   apply(rule_tac prime_cn, auto)+
  1110   apply(rule_tac prime_cn, auto)+
  1126   apply(case_tac i, auto intro: prime_id)
  1111   apply(case_tac i, auto intro: prime_id)
  1127   done
  1112   done
  1128 
  1113 
  1129 lemma [intro]: "primerec rec_noteq (Suc (Suc 0))"
  1114 lemma primerec_rec_noteq_2[intro]: "primerec rec_noteq (Suc (Suc 0))"
  1130 apply(simp add: rec_noteq_def)
  1115 apply(simp add: rec_noteq_def)
  1131 apply(rule_tac prime_cn, auto)+
  1116 apply(rule_tac prime_cn, auto)+
  1132 apply(case_tac i, auto intro: prime_id)
  1117 apply(case_tac i, auto intro: prime_id)
  1133 done
  1118 done
  1134 
  1119 
  1187 
  1172 
  1188 text {*
  1173 text {*
  1189   The correctness of @{text "rec_mod"}:
  1174   The correctness of @{text "rec_mod"}:
  1190   *}
  1175   *}
  1191 lemma mod_lemma: "\<And> x y. rec_exec rec_mod [x, y] = (x mod y)"
  1176 lemma mod_lemma: "\<And> x y. rec_exec rec_mod [x, y] = (x mod y)"
  1192 proof(simp add: rec_exec.simps rec_mod_def quo_lemma2)
  1177   by(simp add: rec_exec.simps rec_mod_def quo_lemma2 minus_div_mult_eq_mod)
  1193   fix x y
       
  1194   show "x - x div y * y = x mod (y::nat)"
       
  1195     using mod_div_equality2[of y x]
       
  1196     apply(subgoal_tac "y * (x div y) = (x div y ) * y", arith, simp)
       
  1197     done
       
  1198 qed
       
  1199 
  1178 
  1200 text{* lemmas for embranch function*}
  1179 text{* lemmas for embranch function*}
  1201 type_synonym ftype = "nat list \<Rightarrow> nat"
  1180 type_synonym ftype = "nat list \<Rightarrow> nat"
  1202 type_synonym rtype = "nat list \<Rightarrow> bool"
  1181 type_synonym rtype = "nat list \<Rightarrow> bool"
  1203 
  1182 
  1602 fun fac :: "nat \<Rightarrow> nat"  ("_!" [100] 99)
  1581 fun fac :: "nat \<Rightarrow> nat"  ("_!" [100] 99)
  1603   where
  1582   where
  1604   "fac 0 = 1" |
  1583   "fac 0 = 1" |
  1605   "fac (Suc x) = (Suc x) * fac x"
  1584   "fac (Suc x) = (Suc x) * fac x"
  1606 
  1585 
  1607 lemma [simp]: "rec_exec rec_dummyfac [0, 0] = Suc 0"
  1586 lemma rec_exec_rec_dummyfac_0: "rec_exec rec_dummyfac [0, 0] = Suc 0"
  1608 by(simp add: rec_dummyfac_def rec_exec.simps)
  1587 by(simp add: rec_dummyfac_def rec_exec.simps)
  1609 
  1588 
  1610 lemma rec_cn_simp: "rec_exec (Cn n f gs) xs = 
  1589 lemma rec_cn_simp: "rec_exec (Cn n f gs) xs = 
  1611                 (let rgs = map (\<lambda> g. rec_exec g xs) gs in
  1590                 (let rgs = map (\<lambda> g. rec_exec g xs) gs in
  1612                  rec_exec f rgs)"
  1591                  rec_exec f rgs)"
  1646   where
  1625   where
  1647   "rec_np = (let Rr = Cn 2 rec_conj [Cn 2 rec_less [id 2 0, id 2 1], 
  1626   "rec_np = (let Rr = Cn 2 rec_conj [Cn 2 rec_less [id 2 0, id 2 1], 
  1648   Cn 2 rec_prime [id 2 1]]
  1627   Cn 2 rec_prime [id 2 1]]
  1649              in Cn 1 (rec_Minr Rr) [id 1 0, Cn 1 s [rec_fac]])"
  1628              in Cn 1 (rec_Minr Rr) [id 1 0, Cn 1 s [rec_fac]])"
  1650 
  1629 
  1651 lemma [simp]: "n < Suc (n!)"
  1630 lemma n_le_fact[simp]: "n < Suc (n!)"
  1652 apply(induct n, simp)
  1631 apply(induct n, simp)
  1653 apply(simp add: fac.simps)
  1632 apply(simp add: fac.simps)
  1654 apply(case_tac n, auto simp: fac.simps)
  1633 apply(case_tac n, auto simp: fac.simps)
  1655 done
  1634 done
  1656 
  1635 
  1665 apply(erule_tac x = u in allE, simp)
  1644 apply(erule_tac x = u in allE, simp)
  1666 apply(case_tac "Prime u", simp)
  1645 apply(case_tac "Prime u", simp)
  1667 apply(rule_tac x = u in exI, simp, auto)
  1646 apply(rule_tac x = u in exI, simp, auto)
  1668 done
  1647 done
  1669 
  1648 
  1670 lemma [intro]: "0 < n!"
  1649 lemma fact_pos[intro]: "0 < n!"
  1671 apply(induct n)
  1650 apply(induct n)
  1672 apply(auto simp: fac.simps)
  1651 apply(auto simp: fac.simps)
  1673 done
  1652 done
  1674 
  1653 
  1675 lemma fac_Suc: "Suc n! =  (Suc n) * (n!)" by(simp add: fac.simps)
  1654 lemma fac_Suc: "Suc n! =  (Suc n) * (n!)" by(simp add: fac.simps)
  1738   
  1717   
  1739 lemma Suc_Suc_induct[elim!]: "\<lbrakk>i < Suc (Suc 0); 
  1718 lemma Suc_Suc_induct[elim!]: "\<lbrakk>i < Suc (Suc 0); 
  1740   primerec (ys ! 0) n; primerec (ys ! 1) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n"
  1719   primerec (ys ! 0) n; primerec (ys ! 1) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n"
  1741 by(case_tac i, auto)
  1720 by(case_tac i, auto)
  1742 
  1721 
  1743 lemma [intro]: "primerec rec_prime (Suc 0)"
  1722 lemma primerec_rec_prime_1[intro]: "primerec rec_prime (Suc 0)"
  1744 apply(auto simp: rec_prime_def, auto)
  1723 apply(auto simp: rec_prime_def, auto)
  1745 apply(rule_tac primerec_all_iff, auto, auto)
  1724 apply(rule_tac primerec_all_iff, auto, auto)
  1746 apply(rule_tac primerec_all_iff, auto, auto simp:  
  1725 apply(rule_tac primerec_all_iff, auto, auto simp:  
  1747   numeral_2_eq_2 numeral_3_eq_3)
  1726   numeral_2_eq_2 numeral_3_eq_3)
  1748 done
  1727 done
  1833   "lo x y  = (if x > 1 \<and> y > 1 \<and> {u. loR [x, y, u]} \<noteq> {} then Max {u. loR [x, y, u]}
  1812   "lo x y  = (if x > 1 \<and> y > 1 \<and> {u. loR [x, y, u]} \<noteq> {} then Max {u. loR [x, y, u]}
  1834                                                          else 0)"
  1813                                                          else 0)"
  1835 
  1814 
  1836 declare lo.simps[simp del]
  1815 declare lo.simps[simp del]
  1837 
  1816 
  1838 lemma [elim]: "primerec rf n \<Longrightarrow> n > 0"
  1817 lemma primerec_then_ge_0[elim]: "primerec rf n \<Longrightarrow> n > 0"
  1839 apply(induct rule: primerec.induct, auto)
  1818 apply(induct rule: primerec.induct, auto)
  1840 done
  1819 done
  1841 
  1820 
  1842 lemma primerec_sigma[intro!]:  
  1821 lemma primerec_sigma[intro!]:  
  1843   "\<lbrakk>n > Suc 0; primerec rf n\<rbrakk> \<Longrightarrow> 
  1822   "\<lbrakk>n > Suc 0; primerec rf n\<rbrakk> \<Longrightarrow> 
  1844   primerec (rec_sigma rf) n"
  1823   primerec (rec_sigma rf) n"
  1845 apply(simp add: rec_sigma.simps)
  1824 apply(simp add: rec_sigma.simps)
  1846 apply(auto, auto simp: nth_append)
  1825 apply(auto, auto simp: nth_append)
  1847 done
  1826 done
  1848 
  1827 
  1849 lemma [intro!]:  "\<lbrakk>primerec rf n; n > 0\<rbrakk> \<Longrightarrow> primerec (rec_maxr rf) n"
  1828 lemma primerec_rec_maxr[intro!]:  "\<lbrakk>primerec rf n; n > 0\<rbrakk> \<Longrightarrow> primerec (rec_maxr rf) n"
  1850 apply(simp add: rec_maxr.simps)
  1829 apply(simp add: rec_maxr.simps)
  1851 apply(rule_tac prime_cn, auto)
  1830 apply(rule_tac prime_cn, auto)
  1852 apply(rule_tac primerec_all_iff, auto, auto simp: nth_append)
  1831 apply(rule_tac primerec_all_iff, auto, auto simp: nth_append)
  1853 done
  1832 done
  1854 
  1833 
  1857   primerec (ys ! 1) n;  
  1836   primerec (ys ! 1) n;  
  1858   primerec (ys ! 2) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n"
  1837   primerec (ys ! 2) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n"
  1859 apply(case_tac i, auto, case_tac nat, simp, simp add: numeral_2_eq_2)
  1838 apply(case_tac i, auto, case_tac nat, simp, simp add: numeral_2_eq_2)
  1860 done
  1839 done
  1861 
  1840 
  1862 lemma [intro]: "primerec rec_quo (Suc (Suc 0))"
  1841 lemma primerec_2[intro]:
  1863 apply(simp add: rec_quo_def)
  1842 "primerec rec_quo (Suc (Suc 0))" "primerec rec_mod (Suc (Suc 0))"
  1864 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  1843 "primerec rec_power (Suc (Suc 0))"
  1865     @{thm prime_id}] 1*}, auto+)+
  1844   by(force simp: prime_cn prime_id rec_mod_def rec_quo_def rec_power_def prime_pr numeral)+
  1866 done
       
  1867 
       
  1868 lemma [intro]: "primerec rec_mod (Suc (Suc 0))"
       
  1869 apply(simp add: rec_mod_def)
       
  1870 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  1871     @{thm prime_id}] 1*}, auto+)+
       
  1872 done
       
  1873 
       
  1874 lemma [intro]: "primerec rec_power (Suc (Suc 0))"
       
  1875 apply(simp add: rec_power_def  numeral_2_eq_2 numeral_3_eq_3)
       
  1876 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  1877     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  1878 done
       
  1879 
  1845 
  1880 text {*
  1846 text {*
  1881   @{text "rec_lo"} is the recursive function used to implement @{text "Lo"}.
  1847   @{text "rec_lo"} is the recursive function used to implement @{text "Lo"}.
  1882 *}
  1848 *}
  1883 definition rec_lo :: "recf"
  1849 definition rec_lo :: "recf"
  1917     Maxr loR [x, y] x"
  1883     Maxr loR [x, y] x"
  1918     apply(simp)
  1884     apply(simp)
  1919     done
  1885     done
  1920 qed
  1886 qed
  1921 
  1887 
  1922 lemma [simp]: "Max {ya. ya = 0 \<and> loR [0, y, ya]} = 0"
  1888 lemma MaxloR0[simp]: "Max {ya. ya = 0 \<and> loR [0, y, ya]} = 0"
  1923 apply(rule_tac Max_eqI, auto simp: loR.simps)
  1889 apply(rule_tac Max_eqI, auto simp: loR.simps)
  1924 done
  1890 done
  1925 
  1891 
  1926 lemma [simp]: "Suc 0 < y \<Longrightarrow> Suc (Suc 0) < y * y"
  1892 lemma two_less_square[simp]: "Suc 0 < y \<Longrightarrow> Suc (Suc 0) < y * y"
  1927 apply(induct y, simp)
  1893   by(induct y, auto)
  1928 apply(case_tac y, simp, simp)
       
  1929 done
       
  1930 
  1894 
  1931 lemma less_mult: "\<lbrakk>x > 0; y > Suc 0\<rbrakk> \<Longrightarrow> x < y * x"
  1895 lemma less_mult: "\<lbrakk>x > 0; y > Suc 0\<rbrakk> \<Longrightarrow> x < y * x"
  1932 apply(case_tac y, simp, simp)
  1896 apply(case_tac y, simp, simp)
  1933 done
  1897 done
  1934 
  1898 
  1940 done
  1904 done
  1941 
  1905 
  1942 lemma le_mult: "y \<noteq> (0::nat) \<Longrightarrow> x \<le> x * y"  
  1906 lemma le_mult: "y \<noteq> (0::nat) \<Longrightarrow> x \<le> x * y"  
  1943   by(induct y, simp, simp)
  1907   by(induct y, simp, simp)
  1944 
  1908 
  1945 lemma uplimit_loR:  "\<lbrakk>Suc 0 < x; Suc 0 < y; loR [x, y, xa]\<rbrakk> \<Longrightarrow> 
  1909 lemma uplimit_loR:
  1946   xa \<le> x"
  1910   assumes "Suc 0 < x" "Suc 0 < y" "loR [x, y, xa]"
  1947 apply(simp add: loR.simps)
  1911   shows "xa \<le> x"
  1948 apply(rule_tac classical, auto)
  1912 proof -
  1949 apply(subgoal_tac "xa < y^xa")
  1913   have "Suc 0 < x \<Longrightarrow> Suc 0 < y \<Longrightarrow> y ^ xa dvd x \<Longrightarrow> xa \<le> x" 
  1950 apply(subgoal_tac "y^xa \<le> y^xa * q", simp)
  1914   by (meson Suc_lessD le_less_trans nat_dvd_not_less nat_le_linear x_less_exp)
  1951 apply(rule_tac le_mult, case_tac q, simp, simp)
  1915   thus ?thesis using assms by(auto simp: loR.simps)
  1952 apply(rule_tac x_less_exp, simp)
  1916 qed
  1953 done
  1917 
  1954 
  1918 lemma loR_set_strengthen[simp]: "\<lbrakk>xa \<le> x; loR [x, y, xa]; Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow>
  1955 lemma [simp]: "\<lbrakk>xa \<le> x; loR [x, y, xa]; Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow>
       
  1956   {u. loR [x, y, u]} = {ya. ya \<le> x \<and> loR [x, y, ya]}"
  1919   {u. loR [x, y, u]} = {ya. ya \<le> x \<and> loR [x, y, ya]}"
  1957 apply(rule_tac Collect_cong, auto)
  1920 apply(rule_tac Collect_cong, auto)
  1958 apply(erule_tac uplimit_loR, simp, simp)
  1921 apply(erule_tac uplimit_loR, simp, simp)
  1959 done
  1922 done
  1960 
  1923 
  2041     done 
  2004     done 
  2042   ultimately show "rec_exec (rec_maxr ?rR) [x, y, x] = Maxr lgR [x, y] x"
  2005   ultimately show "rec_exec (rec_maxr ?rR) [x, y, x] = Maxr lgR [x, y] x"
  2043     by simp
  2006     by simp
  2044 qed
  2007 qed
  2045 
  2008 
  2046 lemma [simp]: "\<lbrakk>Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow> xa \<le> x"
  2009 lemma lgR_ok: "\<lbrakk>Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow> xa \<le> x"
  2047 apply(simp add: lgR.simps)
  2010 apply(simp add: lgR.simps)
  2048 apply(subgoal_tac "y^xa > xa", simp)
  2011 apply(subgoal_tac "y^xa > xa", simp)
  2049 apply(erule x_less_exp)
  2012 apply(erule x_less_exp)
  2050 done
  2013 done
  2051 
  2014 
  2052 lemma [simp]: "\<lbrakk>Suc 0 < x; Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow>
  2015 lemma lgR_set_strengthen[simp]: "\<lbrakk>Suc 0 < x; Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow>
  2053            {u. lgR [x, y, u]} =  {ya. ya \<le> x \<and> lgR [x, y, ya]}"
  2016            {u. lgR [x, y, u]} =  {ya. ya \<le> x \<and> lgR [x, y, ya]}"
  2054 apply(rule_tac Collect_cong, auto)
  2017 apply(rule_tac Collect_cong, auto simp:lgR_ok)
  2055 done
  2018 done
  2056 
  2019 
  2057 lemma maxr_lg: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> Maxr lgR [x, y] x = lg x y"
  2020 lemma maxr_lg: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> Maxr lgR [x, y] x = lg x y"
  2058 apply(simp add: lg.simps Maxr.simps, auto)
  2021 apply(simp add: lg.simps Maxr.simps, auto)
  2059 apply(erule_tac x = xa in allE, simp)
  2022 apply(erule_tac x = xa in allE, auto simp:lgR_ok)
  2060 done
  2023 done
  2061 
  2024 
  2062 lemma lg_lemma': "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y"
  2025 lemma lg_lemma': "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y"
  2063 apply(simp add: maxr_lg lg_maxr)
  2026 apply(simp add: maxr_lg lg_maxr)
  2064 done
  2027 done
  2443 apply(case_tac nat, auto)
  2406 apply(case_tac nat, auto)
  2444 apply(case_tac nata, auto simp: numeral_2_eq_2)
  2407 apply(case_tac nata, auto simp: numeral_2_eq_2)
  2445 apply(case_tac nat, auto simp: numeral_3_eq_3 numeral_4_eq_4)
  2408 apply(case_tac nat, auto simp: numeral_3_eq_3 numeral_4_eq_4)
  2446 done
  2409 done
  2447 
  2410 
  2448 lemma [intro]: "primerec rec_scan (Suc 0)"
  2411 lemma primerec_rec_scan_1[intro]: "primerec rec_scan (Suc 0)"
  2449 apply(auto simp: rec_scan_def, auto)
  2412 apply(auto simp: rec_scan_def, auto)
  2450 done
  2413 done
  2451 
  2414 
  2452 text {*
  2415 text {*
  2453   The correctness of @{text "rec_newrght"}.
  2416   The correctness of @{text "rec_newrght"}.
  2680           rule_tac x = "last xs" in exI)
  2643           rule_tac x = "last xs" in exI)
  2681     apply(case_tac "xs \<noteq> []", auto)
  2644     apply(case_tac "xs \<noteq> []", auto)
  2682     done
  2645     done
  2683 qed
  2646 qed
  2684 
  2647 
  2685 lemma [elim]: 
  2648 lemma nonempty_listE: 
  2686   "Suc 0 \<le> length xs \<Longrightarrow> 
  2649   "Suc 0 \<le> length xs \<Longrightarrow> 
  2687      (map ((\<lambda>a. rec_exec a (m # xs)) \<circ> 
  2650      (map ((\<lambda>a. rec_exec a (m # xs)) \<circ> 
  2688          (\<lambda>i. recf.id (Suc (length xs)) (i))) 
  2651          (\<lambda>i. recf.id (Suc (length xs)) (i))) 
  2689              [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs"
  2652              [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs"
  2690 using map_cons_eq[of m xs]
  2653 using map_cons_eq[of m xs]
  2701                  trpl_lemma inpt.simps strt_lemma)
  2664                  trpl_lemma inpt.simps strt_lemma)
  2702 apply(subgoal_tac
  2665 apply(subgoal_tac
  2703   "(map ((\<lambda>a. rec_exec a (m # xs)) \<circ> 
  2666   "(map ((\<lambda>a. rec_exec a (m # xs)) \<circ> 
  2704           (\<lambda>i. recf.id (Suc (length xs)) (i))) 
  2667           (\<lambda>i. recf.id (Suc (length xs)) (i))) 
  2705             [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs", simp)
  2668             [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs", simp)
  2706 apply(auto, case_tac xs, auto)
  2669 apply(auto elim:nonempty_listE, case_tac xs, auto)
  2707 done
  2670 done
  2708 
  2671 
  2709 definition rec_newconf:: "recf"
  2672 definition rec_newconf:: "recf"
  2710   where
  2673   where
  2711   "rec_newconf = 
  2674   "rec_newconf = 
  2876 declare nonstop.simps[simp del]
  2839 declare nonstop.simps[simp del]
  2877 
  2840 
  2878 lemma primerec_not0: "primerec f n \<Longrightarrow> n > 0"
  2841 lemma primerec_not0: "primerec f n \<Longrightarrow> n > 0"
  2879 by(induct f n rule: primerec.induct, auto)
  2842 by(induct f n rule: primerec.induct, auto)
  2880 
  2843 
  2881 lemma [elim]: "primerec f 0 \<Longrightarrow> RR"
  2844 lemma primerec_not0E[elim]: "primerec f 0 \<Longrightarrow> RR"
  2882 apply(drule_tac primerec_not0, simp)
  2845 apply(drule_tac primerec_not0, simp)
  2883 done
  2846 done
  2884 
  2847 
  2885 lemma [simp]: "length xs = Suc n \<Longrightarrow> length (butlast xs) = n"
  2848 lemma length_butlast[simp]: "length xs = Suc n \<Longrightarrow> length (butlast xs) = n"
  2886 apply(subgoal_tac "\<exists> y ys. xs = ys @ [y]", auto)
  2849 apply(subgoal_tac "\<exists> y ys. xs = ys @ [y]",force)
  2887 apply(rule_tac x = "last xs" in exI)
  2850 apply(rule_tac x = "last xs" in exI)
  2888 apply(rule_tac x = "butlast xs" in exI)
  2851 apply(rule_tac x = "butlast xs" in exI)
  2889 apply(case_tac "xs = []", auto)
  2852 apply(case_tac "xs = []", auto)
  2890 done
  2853 done
  2891 
  2854 
  2892 text {*
  2855 text {*
  2893   The lemma relates the interpreter of primitive fucntions with
  2856   The lemma relates the interpreter of primitive functions with
  2894   the calculation relation of general recursive functions. 
  2857   the calculation relation of general recursive functions. 
  2895   *}
  2858   *}
  2896         
  2859         
  2897 declare numeral_2_eq_2[simp] numeral_3_eq_3[simp]
  2860 declare numeral_2_eq_2[simp] numeral_3_eq_3[simp]
  2898 
  2861 
  2899 lemma [intro]: "primerec rec_right (Suc 0)"
  2862 lemma primerec_rec_right_1[intro]: "primerec rec_right (Suc 0)"
  2900 apply(simp add: rec_right_def rec_lo_def Let_def)
  2863   by(auto simp: rec_right_def rec_lo_def Let_def;force)
  2901 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2864 
       
  2865 lemma primerec_rec_pi_helper:
       
  2866   "\<forall>i<Suc (Suc 0). primerec ([recf.id (Suc 0) 0, recf.id (Suc 0) 0] ! i) (Suc 0)"
       
  2867   by fastforce
       
  2868 
       
  2869 lemmas primerec_rec_pi_helpers =
       
  2870   primerec_rec_pi_helper primerec_constn_1 primerec_rec_sg_1 primerec_rec_not_1 primerec_rec_conj_2
       
  2871 
       
  2872 lemma primrec_dummyfac:
       
  2873   "\<forall>i<Suc (Suc 0).
       
  2874        primerec
       
  2875         ([recf.id (Suc 0) 0,
       
  2876           Cn (Suc 0) s
       
  2877            [Cn (Suc 0) rec_dummyfac
       
  2878              [recf.id (Suc 0) 0, recf.id (Suc 0) 0]]] !
       
  2879          i)
       
  2880         (Suc 0)"
       
  2881   by(auto simp: rec_dummyfac_def;force)
       
  2882 
       
  2883 lemma primerec_rec_pi_1[intro]:  "primerec rec_pi (Suc 0)"
       
  2884   apply(simp add: rec_pi_def rec_dummy_pi_def 
       
  2885                   rec_np_def rec_fac_def rec_prime_def
       
  2886                   rec_Minr.simps Let_def get_fstn_args.simps
       
  2887                   arity.simps
       
  2888                   rec_all.simps rec_sigma.simps rec_accum.simps)
       
  2889   apply(tactic {* resolve_tac @{context} [@{thm prime_cn},  @{thm prime_pr}] 1*}
       
  2890        ;(simp add:primerec_rec_pi_helpers primrec_dummyfac)?)+
       
  2891   by fastforce+
       
  2892 
       
  2893 lemma primerec_rec_trpl[intro]: "primerec rec_trpl (Suc (Suc (Suc 0)))"
       
  2894 apply(simp add: rec_trpl_def)
       
  2895 apply(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  2902     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2896     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2903 done
  2897 done
  2904 
  2898 
  2905 lemma [intro]:  "primerec rec_pi (Suc 0)"
  2899 lemma primerec_rec_listsum2[intro!]: "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_listsum2 vl n) vl"
  2906 apply(simp add: rec_pi_def rec_dummy_pi_def 
       
  2907                 rec_np_def rec_fac_def rec_prime_def
       
  2908                 rec_Minr.simps Let_def get_fstn_args.simps
       
  2909                 arity.simps
       
  2910                 rec_all.simps rec_sigma.simps rec_accum.simps)
       
  2911 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2912     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2913 apply(simp add: rec_dummyfac_def)
       
  2914 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2915     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2916 done
       
  2917 
       
  2918 lemma [intro]: "primerec rec_trpl (Suc (Suc (Suc 0)))"
       
  2919 apply(simp add: rec_trpl_def)
       
  2920 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2921     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2922 done
       
  2923 
       
  2924 lemma [intro!]: "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_listsum2 vl n) vl"
       
  2925 apply(induct n)
  2900 apply(induct n)
  2926 apply(simp_all add: rec_strt'.simps Let_def rec_listsum2.simps)
  2901 apply(simp_all add: rec_strt'.simps Let_def rec_listsum2.simps)
  2927 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2902 apply(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  2928     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2903     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2929 done
  2904 done
  2930 
  2905 
  2931 lemma [elim]: "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_strt' vl n) vl"
  2906 lemma primerec_rec_strt': "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_strt' vl n) vl"
  2932 apply(induct n)
  2907 apply(induct n)
  2933 apply(simp_all add: rec_strt'.simps Let_def)
  2908 apply(simp_all add: rec_strt'.simps Let_def)
  2934 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2909 apply(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  2935     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)
  2910     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)
  2936 done
  2911 done
  2937 
  2912 
  2938 lemma [elim]: "vl > 0 \<Longrightarrow> primerec (rec_strt vl) vl"
  2913 lemma primerec_rec_strt: "vl > 0 \<Longrightarrow> primerec (rec_strt vl) vl"
  2939 apply(simp add: rec_strt.simps rec_strt'.simps)
  2914 apply(simp add: rec_strt.simps rec_strt'.simps)
  2940 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2915 by(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  2941     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2916     @{thm prime_id}, @{thm prime_pr}] 1*}; force elim:primerec_rec_strt')
  2942 done
  2917 
  2943 
  2918 lemma primerec_map_vl: 
  2944 lemma [elim]: 
       
  2945   "i < vl \<Longrightarrow> primerec ((map (\<lambda>i. recf.id (Suc vl) (i)) 
  2919   "i < vl \<Longrightarrow> primerec ((map (\<lambda>i. recf.id (Suc vl) (i)) 
  2946         [Suc 0..<vl] @ [recf.id (Suc vl) (vl)]) ! i) (Suc vl)"
  2920         [Suc 0..<vl] @ [recf.id (Suc vl) (vl)]) ! i) (Suc vl)"
  2947 apply(induct i, auto simp: nth_append)
  2921 apply(induct i, auto simp: nth_append)
  2948 done
  2922 done
  2949 
  2923 
  2950 lemma [intro]: "primerec rec_newleft0 ((Suc (Suc 0)))"
  2924 lemma primerec_recs[intro]:
  2951 apply(simp add: rec_newleft_def rec_embranch.simps 
  2925   "primerec rec_newleft0 (Suc (Suc 0))"
  2952                 Let_def arity.simps rec_newleft0_def
  2926   "primerec rec_newleft1 (Suc (Suc 0))"
       
  2927 "primerec rec_newleft2 (Suc (Suc 0))"
       
  2928 "primerec rec_newleft3 ((Suc (Suc 0)))"
       
  2929 "primerec rec_newleft (Suc (Suc (Suc 0)))"
       
  2930 "primerec rec_left (Suc 0)"
       
  2931 "primerec rec_actn (Suc (Suc (Suc 0)))"
       
  2932 "primerec rec_stat (Suc 0)"
       
  2933 "primerec rec_newstat (Suc (Suc (Suc 0)))"
       
  2934 apply(simp_all add: rec_newleft_def rec_embranch.simps rec_left_def rec_lo_def rec_entry_def
       
  2935                 rec_actn_def Let_def arity.simps rec_newleft0_def rec_stat_def rec_newstat_def
  2953                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
  2936                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
  2954 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2937 apply(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  2955     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2938     @{thm prime_id}, @{thm prime_pr}] 1*};force)+
  2956 done
  2939   done
  2957 
  2940 
  2958 lemma [intro]: "primerec rec_newleft1 ((Suc (Suc 0)))"
  2941 lemma primerec_rec_newrght[intro]: "primerec rec_newrght (Suc (Suc (Suc 0)))"
  2959 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  2960                 Let_def arity.simps rec_newleft0_def
       
  2961                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  2962 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2963     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2964 done
       
  2965 
       
  2966 lemma [intro]: "primerec rec_newleft2 ((Suc (Suc 0)))"
       
  2967 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  2968                 Let_def arity.simps rec_newleft0_def
       
  2969                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  2970 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2971     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2972 done
       
  2973 
       
  2974 lemma [intro]: "primerec rec_newleft3 ((Suc (Suc 0)))"
       
  2975 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  2976                 Let_def arity.simps rec_newleft0_def
       
  2977                 rec_newleft1_def rec_newleft2_def rec_newleft3_def)
       
  2978 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2979     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2980 done
       
  2981 
       
  2982 lemma [intro]: "primerec rec_newleft (Suc (Suc (Suc 0)))"
       
  2983 apply(simp add: rec_newleft_def rec_embranch.simps 
       
  2984                 Let_def arity.simps)
       
  2985 apply(rule_tac prime_cn, auto+)
       
  2986 done
       
  2987 
       
  2988 lemma [intro]: "primerec rec_left (Suc 0)"
       
  2989 apply(simp add: rec_left_def rec_lo_def rec_entry_def Let_def)
       
  2990 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2991     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2992 done
       
  2993 
       
  2994 lemma [intro]: "primerec rec_actn (Suc (Suc (Suc 0)))"
       
  2995 apply(simp add: rec_left_def rec_lo_def rec_entry_def
       
  2996                 Let_def rec_actn_def)
       
  2997 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  2998     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  2999 done
       
  3000 
       
  3001 lemma [intro]: "primerec rec_stat (Suc 0)"
       
  3002 apply(simp add: rec_left_def rec_lo_def rec_entry_def Let_def 
       
  3003                 rec_actn_def rec_stat_def)
       
  3004 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3005     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3006 done
       
  3007 
       
  3008 lemma [intro]: "primerec rec_newstat (Suc (Suc (Suc 0)))"
       
  3009 apply(simp add: rec_left_def rec_lo_def rec_entry_def 
       
  3010                 Let_def rec_actn_def rec_stat_def rec_newstat_def)
       
  3011 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3012     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3013 done
       
  3014 
       
  3015 lemma [intro]: "primerec rec_newrght (Suc (Suc (Suc 0)))"
       
  3016 apply(simp add: rec_newrght_def rec_embranch.simps
  2942 apply(simp add: rec_newrght_def rec_embranch.simps
  3017                 Let_def arity.simps rec_newrgt0_def 
  2943                 Let_def arity.simps rec_newrgt0_def 
  3018                 rec_newrgt1_def rec_newrgt2_def rec_newrgt3_def)
  2944                 rec_newrgt1_def rec_newrgt2_def rec_newrgt3_def)
  3019 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2945 apply(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  3020     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2946     @{thm prime_id}, @{thm prime_pr}] 1*};force)+
  3021 done
  2947 done
  3022 
  2948 
  3023 lemma [intro]: "primerec rec_newconf (Suc (Suc 0))"
  2949 lemma primerec_rec_newconf[intro]: "primerec rec_newconf (Suc (Suc 0))"
  3024 apply(simp add: rec_newconf_def)
  2950 apply(simp add: rec_newconf_def)
  3025 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2951 by(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  3026     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2952     @{thm prime_id}, @{thm prime_pr}] 1*};force)
  3027 done
  2953 
  3028 
  2954 lemma primerec_rec_inpt[intro]: "0 < vl \<Longrightarrow> primerec (rec_inpt (Suc vl)) (Suc vl)"
  3029 lemma [intro]: "0 < vl \<Longrightarrow> primerec (rec_inpt (Suc vl)) (Suc vl)"
       
  3030 apply(simp add: rec_inpt_def)
  2955 apply(simp add: rec_inpt_def)
  3031 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2956 apply(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  3032     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2957     @{thm prime_id}, @{thm prime_pr}] 1*}; fastforce elim:primerec_rec_strt primerec_map_vl)
  3033 done
  2958 done
  3034 
  2959 
  3035 lemma [intro]: "primerec rec_conf (Suc (Suc (Suc 0)))"
  2960 lemma primerec_rec_conf[intro]: "primerec rec_conf (Suc (Suc (Suc 0)))"
  3036 apply(simp add: rec_conf_def)
  2961 apply(simp add: rec_conf_def)
  3037 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2962 by(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  3038     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2963     @{thm prime_id}, @{thm prime_pr}] 1*};force simp: numeral)
  3039 apply(auto simp: numeral_4_eq_4)
  2964 
  3040 done
  2965 lemma primerec_recs2[intro]:
  3041 
  2966   "primerec rec_lg (Suc (Suc 0))"
  3042 lemma [intro]: "primerec rec_lg (Suc (Suc 0))"
  2967   "primerec rec_nonstop (Suc (Suc (Suc 0)))"
  3043 apply(simp add: rec_lg_def Let_def)
  2968 apply(simp_all add: rec_lg_def rec_nonstop_def rec_NSTD_def rec_stat_def
  3044 apply(tactic {* resolve_tac [@{thm prime_cn}, 
       
  3045     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
       
  3046 done
       
  3047 
       
  3048 lemma [intro]:  "primerec rec_nonstop (Suc (Suc (Suc 0)))"
       
  3049 apply(simp add: rec_nonstop_def rec_NSTD_def rec_stat_def
       
  3050      rec_lo_def Let_def rec_left_def rec_right_def rec_newconf_def
  2969      rec_lo_def Let_def rec_left_def rec_right_def rec_newconf_def
  3051      rec_newstat_def)
  2970      rec_newstat_def)
  3052 apply(tactic {* resolve_tac [@{thm prime_cn}, 
  2971 by(tactic {* resolve_tac @{context} [@{thm prime_cn}, 
  3053     @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+
  2972     @{thm prime_id}, @{thm prime_pr}] 1*};fastforce)+
  3054 done
       
  3055 
  2973 
  3056 lemma primerec_terminate: 
  2974 lemma primerec_terminate: 
  3057   "\<lbrakk>primerec f x; length xs = x\<rbrakk> \<Longrightarrow> terminate f xs"
  2975   "\<lbrakk>primerec f x; length xs = x\<rbrakk> \<Longrightarrow> terminate f xs"
  3058 proof(induct arbitrary: xs rule: primerec.induct)
  2976 proof(induct arbitrary: xs rule: primerec.induct)
  3059   fix xs
  2977   fix xs
  3085   fix f n g m xs
  3003   fix f n g m xs
  3086   assume ind1: "\<And>xs. length xs = n \<Longrightarrow> terminate f xs"
  3004   assume ind1: "\<And>xs. length xs = n \<Longrightarrow> terminate f xs"
  3087   and ind2: "\<And>xs. length xs = Suc (Suc n) \<Longrightarrow> terminate g xs"
  3005   and ind2: "\<And>xs. length xs = Suc (Suc n) \<Longrightarrow> terminate g xs"
  3088   and h: "primerec f n" " primerec g (Suc (Suc n))" " m = Suc n" "length (xs::nat list) = m"
  3006   and h: "primerec f n" " primerec g (Suc (Suc n))" " m = Suc n" "length (xs::nat list) = m"
  3089   have "\<forall>y<last xs. terminate g (butlast xs @ [y, rec_exec (Pr n f g) (butlast xs @ [y])])"
  3007   have "\<forall>y<last xs. terminate g (butlast xs @ [y, rec_exec (Pr n f g) (butlast xs @ [y])])"
  3090     using h
  3008     using h ind2 by(auto)
  3091     apply(auto) 
       
  3092     by(rule_tac ind2, simp)
       
  3093   moreover have "terminate f (butlast xs)"
  3009   moreover have "terminate f (butlast xs)"
  3094     using ind1[of "butlast xs"] h
  3010     using ind1[of "butlast xs"] h
  3095     by simp
  3011     by simp
  3096  moreover have "length (butlast xs) = n"
  3012  moreover have "length (butlast xs) = n"
  3097    using h by simp
  3013    using h by simp
  3126 
  3042 
  3127 text {*
  3043 text {*
  3128   The correctness of @{text "rec_valu"}.
  3044   The correctness of @{text "rec_valu"}.
  3129 *}
  3045 *}
  3130 lemma value_lemma: "rec_exec rec_valu [r] = valu r"
  3046 lemma value_lemma: "rec_exec rec_valu [r] = valu r"
  3131 apply(simp add: rec_exec.simps rec_valu_def lg_lemma)
  3047   by(simp add: rec_exec.simps rec_valu_def lg_lemma)
  3132 done
  3048 
  3133 
  3049 lemma primerec_rec_valu_1[intro]: "primerec rec_valu (Suc 0)"
  3134 lemma [intro]: "primerec rec_valu (Suc 0)"
  3050   unfolding rec_valu_def
  3135 apply(simp add: rec_valu_def)
  3051   apply(rule prime_cn[of _ "Suc (Suc 0)"])
  3136 apply(rule_tac k = "Suc (Suc 0)" in prime_cn)
  3052   by auto auto
  3137 apply(auto simp: prime_s)
       
  3138 proof -
       
  3139   show "primerec rec_lg (Suc (Suc 0))" by auto
       
  3140 next
       
  3141   show "Suc (Suc 0) = Suc (Suc 0)" by simp
       
  3142 next
       
  3143   show "primerec (constn (Suc (Suc 0))) (Suc 0)" by auto
       
  3144 qed
       
  3145 
  3053 
  3146 declare valu.simps[simp del]
  3054 declare valu.simps[simp del]
  3147 
  3055 
  3148 text {*
  3056 text {*
  3149   The definition of the universal function @{text "rec_F"}.
  3057   The definition of the universal function @{text "rec_F"}.
  3151 definition rec_F :: "recf"
  3059 definition rec_F :: "recf"
  3152   where
  3060   where
  3153   "rec_F = Cn (Suc (Suc 0)) rec_valu [Cn (Suc (Suc 0)) rec_right [Cn (Suc (Suc 0))
  3061   "rec_F = Cn (Suc (Suc 0)) rec_valu [Cn (Suc (Suc 0)) rec_right [Cn (Suc (Suc 0))
  3154  rec_conf ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])]]"
  3062  rec_conf ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])]]"
  3155 
  3063 
  3156 lemma get_fstn_args_nth: 
  3064 lemma get_fstn_args_nth[simp]: 
  3157   "k < n \<Longrightarrow> (get_fstn_args m n ! k) = id m (k)"
  3065   "k < n \<Longrightarrow> (get_fstn_args m n ! k) = id m (k)"
  3158 apply(induct n, simp)
  3066 apply(induct n, simp)
  3159 apply(case_tac "k = n", simp_all add: get_fstn_args.simps 
  3067 apply(case_tac "k = n", simp_all add: get_fstn_args.simps 
  3160                                       nth_append)
  3068                                       nth_append)
  3161 done
  3069 done
  3162 
  3070 
  3163 lemma [simp]: 
  3071 lemma get_fstn_args_is_id[simp]: 
  3164   "\<lbrakk>ys \<noteq> [];
  3072   "\<lbrakk>ys \<noteq> [];
  3165   k < length ys\<rbrakk> \<Longrightarrow>
  3073   k < length ys\<rbrakk> \<Longrightarrow>
  3166   (get_fstn_args (length ys) (length ys) ! k) = 
  3074   (get_fstn_args (length ys) (length ys) ! k) = 
  3167                                   id (length ys) (k)"
  3075                                   id (length ys) (k)"
  3168 by(erule_tac get_fstn_args_nth)
  3076 by(erule_tac get_fstn_args_nth)
  3266   "code tp = (let nl = modify_tprog tp in 
  3174   "code tp = (let nl = modify_tprog tp in 
  3267               godel_code nl)"
  3175               godel_code nl)"
  3268 
  3176 
  3269 subsection {* Relating interperter functions to the execution of TMs *}
  3177 subsection {* Relating interperter functions to the execution of TMs *}
  3270 
  3178 
  3271 lemma [simp]: "bl2wc [] = 0" by(simp add: bl2wc.simps bl2nat.simps)
  3179 lemma bl2wc_0[simp]: "bl2wc [] = 0" by(simp add: bl2wc.simps bl2nat.simps)
  3272 
  3180 
  3273 lemma [simp]: "\<lbrakk>fetch tp 0 b = (nact, ns)\<rbrakk> \<Longrightarrow> action_map nact = 4"
  3181 lemma fetch_action_map_4[simp]: "\<lbrakk>fetch tp 0 b = (nact, ns)\<rbrakk> \<Longrightarrow> action_map nact = 4"
  3274 apply(simp add: fetch.simps)
  3182 apply(simp add: fetch.simps)
  3275 done
  3183 done
  3276 
  3184 
  3277 lemma Pi_gr_1[simp]: "Pi n > Suc 0"
  3185 lemma Pi_gr_1[simp]: "Pi n > Suc 0"
  3278 proof(induct n, auto simp: Pi.simps Np.simps)
  3186 proof(induct n, auto simp: Pi.simps Np.simps)
  3293 using Pi_gr_1[of n]
  3201 using Pi_gr_1[of n]
  3294 by arith
  3202 by arith
  3295 
  3203 
  3296 declare godel_code.simps[simp del]
  3204 declare godel_code.simps[simp del]
  3297 
  3205 
  3298 lemma [simp]: "0 < godel_code' nl n"
  3206 lemma godel_code'_nonzero[simp]: "0 < godel_code' nl n"
  3299 apply(induct nl arbitrary: n)
  3207 apply(induct nl arbitrary: n)
  3300 apply(auto simp: godel_code'.simps)
  3208 apply(auto simp: godel_code'.simps)
  3301 done
  3209 done
  3302 
  3210 
  3303 lemma godel_code_great: "godel_code nl > 0"
  3211 lemma godel_code_great: "godel_code nl > 0"
  3306 
  3214 
  3307 lemma godel_code_eq_1: "(godel_code nl = 1) = (nl = [])"
  3215 lemma godel_code_eq_1: "(godel_code nl = 1) = (nl = [])"
  3308 apply(auto simp: godel_code.simps)
  3216 apply(auto simp: godel_code.simps)
  3309 done
  3217 done
  3310 
  3218 
  3311 lemma [elim]: 
  3219 lemma godel_code_1_iff[elim]: 
  3312   "\<lbrakk>i < length nl; \<not> Suc 0 < godel_code nl\<rbrakk> \<Longrightarrow> nl ! i = 0"
  3220   "\<lbrakk>i < length nl; \<not> Suc 0 < godel_code nl\<rbrakk> \<Longrightarrow> nl ! i = 0"
  3313 using godel_code_great[of nl] godel_code_eq_1[of nl]
  3221 using godel_code_great[of nl] godel_code_eq_1[of nl]
  3314 apply(simp)
  3222 apply(simp)
  3315 done
  3223 done
  3316 
  3224 
  3317 lemma prime_coprime: "\<lbrakk>Prime x; Prime y; x\<noteq>y\<rbrakk> \<Longrightarrow> coprime x y"
  3225 lemma prime_coprime: "\<lbrakk>Prime x; Prime y; x\<noteq>y\<rbrakk> \<Longrightarrow> coprime x y"
  3318 proof(simp only: Prime.simps coprime_nat, auto simp: dvd_def,
  3226 proof (simp only: Prime.simps coprime_def, auto simp: dvd_def,
  3319       rule_tac classical, simp)
  3227       rule_tac classical, simp)
  3320   fix d k ka
  3228   fix d k ka
  3321   assume case_ka: "\<forall>u<d * ka. \<forall>v<d * ka. u * v \<noteq> d * ka" 
  3229   assume case_ka: "\<forall>u<d * ka. \<forall>v<d * ka. u * v \<noteq> d * ka" 
  3322     and case_k: "\<forall>u<d * k. \<forall>v<d * k. u * v \<noteq> d * k"
  3230     and case_k: "\<forall>u<d * k. \<forall>v<d * k. u * v \<noteq> d * k"
  3323     and h: "(0::nat) < d" "d \<noteq> Suc 0" "Suc 0 < d * ka" 
  3231     and h: "(0::nat) < d" "d \<noteq> Suc 0" "Suc 0 < d * ka" 
  3324            "ka \<noteq> k" "Suc 0 < d * k"
  3232            "ka \<noteq> k" "Suc 0 < d * k"
  3325   from h have "k > Suc 0 \<or> ka >Suc 0"
  3233   from h have "k > Suc 0 \<or> ka >Suc 0"
  3326     apply(auto)
  3234     by (cases ka;cases k;force+)
  3327     apply(case_tac ka, simp, simp)
       
  3328     apply(case_tac k, simp, simp)
       
  3329     done
       
  3330   from this show "False"
  3235   from this show "False"
  3331   proof(erule_tac disjE)
  3236   proof(erule_tac disjE)
  3332     assume  "(Suc 0::nat) < k"
  3237     assume  "(Suc 0::nat) < k"
  3333     hence "k < d*k \<and> d < d*k"
  3238     hence "k < d*k \<and> d < d*k"
  3334       using h
  3239       using h
  3400 apply(simp)
  3305 apply(simp)
  3401 using Pi_inc_gr[of j i]
  3306 using Pi_inc_gr[of j i]
  3402 apply(simp)
  3307 apply(simp)
  3403 done
  3308 done
  3404 
  3309 
  3405 lemma [intro]: "Prime (Suc (Suc 0))"
  3310 lemma prime_2[intro]: "Prime (Suc (Suc 0))"
  3406 apply(auto simp: Prime.simps)
  3311 apply(auto simp: Prime.simps)
  3407 apply(case_tac u, simp, case_tac nat, simp, simp)
  3312 apply(case_tac u, simp, case_tac nat, simp, simp)
  3408 done
  3313 done
  3409 
  3314 
  3410 lemma Prime_Pi[intro]: "Prime (Pi n)"
  3315 lemma Prime_Pi[intro]: "Prime (Pi n)"
  3429 using Prime_Pi[of j]
  3334 using Prime_Pi[of j]
  3430 apply(rule_tac prime_coprime, simp_all add: Pi_notEq)
  3335 apply(rule_tac prime_coprime, simp_all add: Pi_notEq)
  3431 done
  3336 done
  3432 
  3337 
  3433 lemma Pi_power_coprime: "i \<noteq> j \<Longrightarrow> coprime ((Pi i)^m) ((Pi j)^n)"
  3338 lemma Pi_power_coprime: "i \<noteq> j \<Longrightarrow> coprime ((Pi i)^m) ((Pi j)^n)"
  3434 by(rule_tac coprime_exp2_nat, erule_tac Pi_coprime)
  3339   unfolding coprime_power_right_iff coprime_power_left_iff using Pi_coprime by auto
  3435 
  3340 
  3436 lemma coprime_dvd_mult_nat2: "\<lbrakk>coprime (k::nat) n; k dvd n * m\<rbrakk> \<Longrightarrow> k dvd m"
  3341 lemma coprime_dvd_mult_nat2: "\<lbrakk>coprime (k::nat) n; k dvd n * m\<rbrakk> \<Longrightarrow> k dvd m"
  3437 apply(erule_tac coprime_dvd_mult_nat)
  3342   unfolding coprime_dvd_mult_right_iff.
  3438 apply(simp add: dvd_def, auto)
       
  3439 apply(rule_tac x = ka in exI)
       
  3440 apply(subgoal_tac "n * m = m * n", simp)
       
  3441 apply(simp add: nat_mult_commute)
       
  3442 done
       
  3443 
  3343 
  3444 declare godel_code'.simps[simp del]
  3344 declare godel_code'.simps[simp del]
  3445 
  3345 
  3446 lemma godel_code'_butlast_last_id' :
  3346 lemma godel_code'_butlast_last_id' :
  3447   "godel_code' (ys @ [y]) (Suc j) = godel_code' ys (Suc j) * 
  3347   "godel_code' (ys @ [y]) (Suc j) = godel_code' ys (Suc j) * 
  3502     done
  3402     done
  3503 qed
  3403 qed
  3504 
  3404 
  3505 lemma Pi_coprime_pre: 
  3405 lemma Pi_coprime_pre: 
  3506   "length ps \<le> i \<Longrightarrow> coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
  3406   "length ps \<le> i \<Longrightarrow> coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
  3507 proof(induct "length ps" arbitrary: ps, simp add: godel_code'.simps)
  3407 proof(induct "length ps" arbitrary: ps)
  3508   fix x ps
  3408   fix x ps
  3509   assume ind: 
  3409   assume ind: 
  3510     "\<And>ps. \<lbrakk>x = length ps; length ps \<le> i\<rbrakk> \<Longrightarrow>
  3410     "\<And>ps. \<lbrakk>x = length ps; length ps \<le> i\<rbrakk> \<Longrightarrow>
  3511                   coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
  3411                   coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
  3512   and h: "Suc x = length ps"
  3412   and h: "Suc x = length ps"
  3516     using h by auto
  3416     using h by auto
  3517   have k: "godel_code' ps (Suc 0) = 
  3417   have k: "godel_code' ps (Suc 0) = 
  3518          godel_code' (butlast ps) (Suc 0) * Pi (length ps)^(last ps)"
  3418          godel_code' (butlast ps) (Suc 0) * Pi (length ps)^(last ps)"
  3519     using godel_code'_butlast_last_id[of ps 0] h 
  3419     using godel_code'_butlast_last_id[of ps 0] h 
  3520     by(case_tac ps, simp, simp)
  3420     by(case_tac ps, simp, simp)
  3521   from g have 
  3421   from g have "coprime (Pi (Suc i)) (Pi (length ps) ^ last ps)"
       
  3422     unfolding coprime_power_right_iff using Pi_coprime h(2) by auto
       
  3423    with g have 
  3522     "coprime (Pi (Suc i)) (godel_code' (butlast ps) (Suc 0) *
  3424     "coprime (Pi (Suc i)) (godel_code' (butlast ps) (Suc 0) *
  3523                                         Pi (length ps)^(last ps)) "
  3425                                         Pi (length ps)^(last ps)) "
  3524   proof(rule_tac coprime_mult_nat, simp)
  3426     unfolding coprime_mult_right_iff coprime_power_right_iff by auto
  3525     show "coprime (Pi (Suc i)) (Pi (length ps) ^ last ps)"
  3427 
  3526       apply(rule_tac coprime_exp_nat, rule prime_coprime, auto)
       
  3527       using Pi_notEq[of "Suc i" "length ps"] h by simp
       
  3528   qed
       
  3529   from this and k show "coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
  3428   from this and k show "coprime (Pi (Suc i)) (godel_code' ps (Suc 0))"
  3530     by simp
  3429     by simp
  3531 qed
  3430 qed (auto simp add: godel_code'.simps)
  3532 
  3431 
  3533 lemma Pi_coprime_suf: "i < j \<Longrightarrow> coprime (Pi i) (godel_code' ps j)"
  3432 lemma Pi_coprime_suf: "i < j \<Longrightarrow> coprime (Pi i) (godel_code' ps j)"
  3534 proof(induct "length ps" arbitrary: ps, simp add: godel_code'.simps)
  3433 proof(induct "length ps" arbitrary: ps)
  3535   fix x ps
  3434   fix x ps
  3536   assume ind: 
  3435   assume ind: 
  3537     "\<And>ps. \<lbrakk>x = length ps; i < j\<rbrakk> \<Longrightarrow> 
  3436     "\<And>ps. \<lbrakk>x = length ps; i < j\<rbrakk> \<Longrightarrow> 
  3538                     coprime (Pi i) (godel_code' ps j)"
  3437                     coprime (Pi i) (godel_code' ps j)"
  3539   and h: "Suc x = length (ps::nat list)" "i < j"
  3438   and h: "Suc x = length (ps::nat list)" "i < j"
  3545     apply(case_tac "ps = []", simp, simp)
  3444     apply(case_tac "ps = []", simp, simp)
  3546     done
  3445     done
  3547   from g have
  3446   from g have
  3548     "coprime (Pi i) (godel_code' (butlast ps) j * 
  3447     "coprime (Pi i) (godel_code' (butlast ps) j * 
  3549                           Pi (length ps + j - 1)^last ps)"
  3448                           Pi (length ps + j - 1)^last ps)"
  3550     apply(rule_tac coprime_mult_nat, simp)
  3449     using Pi_power_coprime[of i "length ps + j - 1" 1 "last ps"] h
  3551     using  Pi_power_coprime[of i "length ps + j - 1" 1 "last ps"] h
  3450     by(auto)
  3552     apply(auto)
       
  3553     done
       
  3554   from k and this show "coprime (Pi i) (godel_code' ps j)"
  3451   from k and this show "coprime (Pi i) (godel_code' ps j)"
  3555     by auto
  3452     by auto
  3556 qed
  3453 qed (simp add: godel_code'.simps)
  3557 
  3454 
  3558 lemma godel_finite: 
  3455 lemma godel_finite: 
  3559   "finite {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
  3456   "finite {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
  3560 proof(rule_tac n = "godel_code' nl (Suc 0)" in 
  3457 proof(rule_tac n = "godel_code' nl (Suc 0)" in 
  3561                           bounded_nat_set_is_finite, auto, 
  3458                           bounded_nat_set_is_finite, auto, 
  3617   proof(simp)
  3514   proof(simp)
  3618     let ?suf' = "godel_code' (drop (Suc i) nl) (Suc (Suc i))"
  3515     let ?suf' = "godel_code' (drop (Suc i) nl) (Suc (Suc i))"
  3619     assume mult_dvd: 
  3516     assume mult_dvd: 
  3620       "Pi (Suc i) ^ y dvd ?pref *  Pi (Suc i) ^ nl ! i * ?suf'"
  3517       "Pi (Suc i) ^ y dvd ?pref *  Pi (Suc i) ^ nl ! i * ?suf'"
  3621     hence "Pi (Suc i) ^ y dvd ?pref * Pi (Suc i) ^ nl ! i"
  3518     hence "Pi (Suc i) ^ y dvd ?pref * Pi (Suc i) ^ nl ! i"
  3622     proof(rule_tac coprime_dvd_mult_nat)
  3519     proof -
  3623       show "coprime (Pi (Suc i)^y) ?suf'"
  3520       have "coprime (Pi (Suc i)^y) ?suf'" by (simp add: Pi_coprime_suf)
  3624       proof -
  3521       thus ?thesis using coprime_dvd_mult_left_iff mult_dvd by blast
  3625         have "coprime (Pi (Suc i) ^ y) (?suf'^(Suc 0))"
       
  3626           apply(rule_tac coprime_exp2_nat)
       
  3627           apply(rule_tac  Pi_coprime_suf, simp)
       
  3628           done
       
  3629         thus "?thesis" by simp
       
  3630       qed
       
  3631     qed
  3522     qed
  3632     hence "Pi (Suc i) ^ y dvd Pi (Suc i) ^ nl ! i"
  3523     hence "Pi (Suc i) ^ y dvd Pi (Suc i) ^ nl ! i"
  3633     proof(rule_tac coprime_dvd_mult_nat2)
  3524     proof(rule_tac coprime_dvd_mult_nat2)
  3634       show "coprime (Pi (Suc i) ^ y) ?pref"
  3525       have "coprime (Pi (Suc i)^y) (?pref^Suc 0)" using Pi_coprime_pre by simp
  3635       proof -
  3526       thus "coprime (Pi (Suc i) ^ y) ?pref" by simp
  3636         have "coprime (Pi (Suc i)^y) (?pref^Suc 0)"
       
  3637           apply(rule_tac coprime_exp2_nat)
       
  3638           apply(rule_tac Pi_coprime_pre, simp)
       
  3639           done
       
  3640         thus "?thesis" by simp
       
  3641       qed
       
  3642     qed
  3527     qed
  3643     hence "Pi (Suc i) ^ y \<le>  Pi (Suc i) ^ nl ! i "
  3528     hence "Pi (Suc i) ^ y \<le>  Pi (Suc i) ^ nl ! i "
  3644       apply(rule_tac dvd_imp_le, auto)
  3529       apply(rule_tac dvd_imp_le, auto)
  3645       done
  3530       done
  3646     thus "y \<le> nl ! i"
  3531     thus "y \<le> nl ! i"
  3652 
  3537 
  3653   thus "nl ! i \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
  3538   thus "nl ! i \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}"
  3654     by(rule_tac godel_code_in, simp)
  3539     by(rule_tac godel_code_in, simp)
  3655 qed
  3540 qed
  3656 
  3541 
  3657 lemma [simp]: 
  3542 lemma godel_code'_set[simp]: 
  3658   "{u. Pi (Suc i) ^ u dvd (Suc (Suc 0)) ^ length nl * 
  3543   "{u. Pi (Suc i) ^ u dvd (Suc (Suc 0)) ^ length nl * 
  3659                                      godel_code' nl (Suc 0)} = 
  3544                                      godel_code' nl (Suc 0)} = 
  3660     {u. Pi (Suc i) ^ u dvd  godel_code' nl (Suc 0)}"
  3545     {u. Pi (Suc i) ^ u dvd  godel_code' nl (Suc 0)}"
  3661 apply(rule_tac Collect_cong, auto)
  3546 apply(rule_tac Collect_cong, auto)
  3662 apply(rule_tac n = " (Suc (Suc 0)) ^ length nl" in 
  3547 apply(rule_tac n = " (Suc (Suc 0)) ^ length nl" in 
  3663                                  coprime_dvd_mult_nat2)
  3548                                  coprime_dvd_mult_nat2)
  3664 proof -
  3549 proof -
  3665   fix u
  3550   have "Pi 0 = (2::nat)" by(simp add: Pi.simps)
  3666   show "coprime (Pi (Suc i) ^ u) ((Suc (Suc 0)) ^ length nl)"
  3551   show "coprime (Pi (Suc i) ^ u) ((Suc (Suc 0)) ^ length nl)" for u
  3667   proof(rule_tac coprime_exp2_nat)
  3552     using Pi_coprime Pi.simps(1) by force
  3668     have "Pi 0 = (2::nat)"
       
  3669       apply(simp add: Pi.simps)
       
  3670       done
       
  3671     moreover have "coprime (Pi (Suc i)) (Pi 0)"
       
  3672       apply(rule_tac Pi_coprime, simp)
       
  3673       done
       
  3674     ultimately show "coprime (Pi (Suc i)) (Suc (Suc 0))" by simp
       
  3675   qed
       
  3676 qed
  3553 qed
  3677   
  3554   
  3678 lemma godel_code_get_nth: 
  3555 lemma godel_code_get_nth: 
  3679   "i < length nl \<Longrightarrow> 
  3556   "i < length nl \<Longrightarrow> 
  3680            Max {u. Pi (Suc i) ^ u dvd godel_code nl} = nl ! i"
  3557            Max {u. Pi (Suc i) ^ u dvd godel_code nl} = nl ! i"
  3681 by(simp add: godel_code.simps godel_code'_get_nth)
  3558 by(simp add: godel_code.simps godel_code'_get_nth)
  3682 
  3559 
  3683 lemma "trpl l st r = godel_code' [l, st, r] 0"
       
  3684 apply(simp add: trpl.simps godel_code'.simps)
       
  3685 done
       
  3686 
       
  3687 lemma mod_dvd_simp: "(x mod y = (0::nat)) = (y dvd x)"
  3560 lemma mod_dvd_simp: "(x mod y = (0::nat)) = (y dvd x)"
  3688 by(simp add: dvd_def, auto)
  3561 by(simp add: dvd_def, auto)
  3689 
  3562 
  3690 lemma dvd_power_le: "\<lbrakk>a > Suc 0; a ^ y dvd a ^ l\<rbrakk> \<Longrightarrow> y \<le> l"
  3563 lemma dvd_power_le: "\<lbrakk>a > Suc 0; a ^ y dvd a ^ l\<rbrakk> \<Longrightarrow> y \<le> l"
  3691 apply(case_tac "y \<le> l", simp, simp)
  3564 apply(case_tac "y \<le> l", simp, simp)
  3692 apply(subgoal_tac "\<exists> d. y = l + d", auto simp: power_add)
  3565 apply(subgoal_tac "\<exists> d. y = l + d", auto simp: power_add)
  3693 apply(rule_tac x = "y - l" in exI, simp)
  3566 apply(rule_tac x = "y - l" in exI, simp)
  3694 done
  3567 done
  3695 
  3568 
  3696 
  3569 
  3697 lemma [elim]: "Pi n = 0 \<Longrightarrow> RR"
  3570 lemma Pi_nonzeroE[elim]: "Pi n = 0 \<Longrightarrow> RR"
  3698   using Pi_not_0[of n] by simp
  3571   using Pi_not_0[of n] by simp
  3699 
  3572 
  3700 lemma [elim]: "Pi n = Suc 0 \<Longrightarrow> RR"
  3573 lemma Pi_not_oneE[elim]: "Pi n = Suc 0 \<Longrightarrow> RR"
  3701   using Pi_gr_1[of n] by simp
  3574   using Pi_gr_1[of n] by simp
  3702 
  3575 
  3703 lemma finite_power_dvd:
  3576 lemma finite_power_dvd:
  3704   "\<lbrakk>(a::nat) > Suc 0; y \<noteq> 0\<rbrakk> \<Longrightarrow> finite {u. a^u dvd y}"
  3577   "\<lbrakk>(a::nat) > Suc 0; y \<noteq> 0\<rbrakk> \<Longrightarrow> finite {u. a^u dvd y}"
  3705 apply(auto simp: dvd_def)
  3578 apply(auto simp: dvd_def)
  3723     fix y
  3596     fix y
  3724     assume h: "y \<in> ?setx"
  3597     assume h: "y \<in> ?setx"
  3725     have "Pi m ^ y dvd Pi m ^ l"
  3598     have "Pi m ^ y dvd Pi m ^ l"
  3726     proof -
  3599     proof -
  3727       have "Pi m ^ y dvd Pi m ^ l * Pi n ^ st"
  3600       have "Pi m ^ y dvd Pi m ^ l * Pi n ^ st"
  3728         using h g
  3601         using h g Pi_power_coprime
  3729         apply(rule_tac n = "Pi k^r" in coprime_dvd_mult_nat)
  3602         by (simp add: coprime_dvd_mult_left_iff)
  3730         apply(rule Pi_power_coprime, simp, simp)
  3603       thus "Pi m^y dvd Pi m^l" using g Pi_power_coprime coprime_dvd_mult_left_iff by blast
  3731         done
       
  3732       thus "Pi m^y dvd Pi m^l"
       
  3733         apply(rule_tac n = " Pi n ^ st" in coprime_dvd_mult_nat)
       
  3734         using g
       
  3735         apply(rule_tac Pi_power_coprime, simp, simp)
       
  3736         done
       
  3737     qed
  3604     qed
  3738     thus "y \<le> (l::nat)"
  3605     thus "y \<le> (l::nat)"
  3739       apply(rule_tac a = "Pi m" in power_le_imp_le_exp)
  3606       apply(rule_tac a = "Pi m" in power_le_imp_le_exp)
  3740       apply(simp_all add: Pi_gr_1)
  3607       apply(simp_all add: Pi_gr_1)
  3741       apply(rule_tac dvd_power_le, auto)
  3608       apply(rule_tac dvd_power_le, auto)
  3749   "\<lbrakk>m \<noteq> n; m \<noteq> k; n \<noteq> k; 
  3616   "\<lbrakk>m \<noteq> n; m \<noteq> k; n \<noteq> k; 
  3750   \<not> Suc 0 < Pi m ^ l * Pi n ^ st * Pi k ^ r\<rbrakk> \<Longrightarrow> l = 0"
  3617   \<not> Suc 0 < Pi m ^ l * Pi n ^ st * Pi k ^ r\<rbrakk> \<Longrightarrow> l = 0"
  3751 apply(case_tac "Pi m ^ l * Pi n ^ st * Pi k ^ r", auto)
  3618 apply(case_tac "Pi m ^ l * Pi n ^ st * Pi k ^ r", auto)
  3752 done
  3619 done
  3753 
  3620 
  3754 lemma [simp]: "left (trpl l st r) = l"
  3621 lemma left_trpl_fst[simp]: "left (trpl l st r) = l"
  3755 apply(simp add: left.simps trpl.simps lo.simps loR.simps mod_dvd_simp)
  3622 apply(simp add: left.simps trpl.simps lo.simps loR.simps mod_dvd_simp)
  3756 apply(auto simp: conf_decode1)
  3623 apply(auto simp: conf_decode1)
  3757 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r")
  3624 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r")
  3758 apply(auto)
  3625 apply(auto)
  3759 apply(erule_tac x = l in allE, auto)
  3626 apply(erule_tac x = l in allE, auto)
  3760 done   
  3627 done   
  3761 
  3628 
  3762 lemma [simp]: "stat (trpl l st r) = st"
  3629 lemma stat_trpl_snd[simp]: "stat (trpl l st r) = st"
  3763 apply(simp add: stat.simps trpl.simps lo.simps 
  3630 apply(simp add: stat.simps trpl.simps lo.simps 
  3764                 loR.simps mod_dvd_simp, auto)
  3631                 loR.simps mod_dvd_simp, auto)
  3765 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r
  3632 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r
  3766                = Pi (Suc 0)^st * Pi 0 ^ l *  Pi (Suc (Suc 0)) ^ r")
  3633                = Pi (Suc 0)^st * Pi 0 ^ l *  Pi (Suc (Suc 0)) ^ r")
  3767 apply(simp (no_asm_simp) add: conf_decode1, simp)
  3634 apply(simp (no_asm_simp) add: conf_decode1, simp)
  3768 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * 
  3635 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * 
  3769                                   Pi (Suc (Suc 0)) ^ r", auto)
  3636                                   Pi (Suc (Suc 0)) ^ r", auto)
  3770 apply(erule_tac x = st in allE, auto)
  3637 apply(erule_tac x = st in allE, auto)
  3771 done
  3638 done
  3772 
  3639 
  3773 lemma [simp]: "rght (trpl l st r) = r"
  3640 lemma rght_trpl_trd[simp]: "rght (trpl l st r) = r"
  3774 apply(simp add: rght.simps trpl.simps lo.simps 
  3641 apply(simp add: rght.simps trpl.simps lo.simps 
  3775                 loR.simps mod_dvd_simp, auto)
  3642                 loR.simps mod_dvd_simp, auto)
  3776 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r
  3643 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r
  3777                = Pi (Suc (Suc 0))^r * Pi 0 ^ l *  Pi (Suc 0) ^ st")
  3644                = Pi (Suc (Suc 0))^r * Pi 0 ^ l *  Pi (Suc 0) ^ st")
  3778 apply(simp (no_asm_simp) add: conf_decode1, simp)
  3645 apply(simp (no_asm_simp) add: conf_decode1, simp)
  3936                       (4 * (st - Suc 0) + 2 * (r mod 2))
  3803                       (4 * (st - Suc 0) + 2 * (r mod 2))
  3937            = action_map nact" 
  3804            = action_map nact" 
  3938     by simp
  3805     by simp
  3939 qed
  3806 qed
  3940 
  3807 
  3941 lemma [simp]: "fetch tp 0 b = (nact, ns) \<Longrightarrow> ns = 0"
  3808 lemma fetch_zero_zero[simp]: "fetch tp 0 b = (nact, ns) \<Longrightarrow> ns = 0"
  3942 by(simp add: fetch.simps)
  3809 by(simp add: fetch.simps)
  3943 
  3810 
  3944 lemma Five_Suc: "5 = Suc 4" by simp
  3811 lemma Five_Suc: "5 = Suc 4" by simp
  3945 
  3812 
  3946 lemma modify_tprog_fetch_state:
  3813 lemma modify_tprog_fetch_state:
  4027            = ns" 
  3894            = ns" 
  4028     by simp
  3895     by simp
  4029 qed
  3896 qed
  4030 
  3897 
  4031 
  3898 
  4032 lemma [intro!]: 
  3899 lemma tpl_eqI[intro!]: 
  4033   "\<lbrakk>a = a'; b = b'; c = c'\<rbrakk> \<Longrightarrow> trpl a b c = trpl a' b' c'"
  3900   "\<lbrakk>a = a'; b = b'; c = c'\<rbrakk> \<Longrightarrow> trpl a b c = trpl a' b' c'"
  4034 by simp
  3901 by simp
  4035 
  3902 
  4036 lemma [simp]: "bl2wc [Bk] = 0"
  3903 lemma bl2wc_Bk[simp]: "bl2wc [Bk] = 0"
  4037 by(simp add: bl2wc.simps bl2nat.simps)
  3904 by(simp add: bl2wc.simps bl2nat.simps)
  4038 
  3905 
  4039 lemma bl2nat_double: "bl2nat xs (Suc n) = 2 * bl2nat xs n"
  3906 lemma bl2nat_double: "bl2nat xs (Suc n) = 2 * bl2nat xs n"
  4040 proof(induct xs arbitrary: n)
  3907 proof(induct xs arbitrary: n)
  4041   case Nil thus "?case"
  3908   case Nil thus "?case"
  4056     qed
  3923     qed
  4057   qed
  3924   qed
  4058 qed
  3925 qed
  4059 
  3926 
  4060 
  3927 
  4061 lemma [simp]: "2 * bl2wc (tl c) = bl2wc c - bl2wc c mod 2 "
  3928 lemma bl2wc_simps[simp]:
  4062 apply(case_tac c, simp, case_tac a)
       
  4063 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4064 done
       
  4065 
       
  4066 lemma [simp]:
       
  4067   "bl2wc (Oc # tl c) = Suc (bl2wc c) - bl2wc c mod 2 "
  3929   "bl2wc (Oc # tl c) = Suc (bl2wc c) - bl2wc c mod 2 "
  4068 apply(case_tac c, case_tac [2] a, simp)
  3930   "bl2wc (Bk # c) = 2*bl2wc (c)"
  4069 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
  3931   "2 * bl2wc (tl c) = bl2wc c - bl2wc c mod 2 "
  4070 done
  3932   "bl2wc [Oc] = Suc 0"
  4071 
  3933   "c \<noteq> [] \<Longrightarrow> bl2wc (tl c) = bl2wc c div 2"
  4072 lemma [simp]: "bl2wc (Bk # c) = 2*bl2wc (c)"
  3934   "c \<noteq> [] \<Longrightarrow> bl2wc [hd c] = bl2wc c mod 2"
  4073 apply(simp add: bl2wc.simps bl2nat.simps bl2nat_double)
  3935   "c \<noteq> [] \<Longrightarrow> bl2wc (hd c # d) = 2 * bl2wc d + bl2wc c mod 2"
  4074 done
  3936   "2 * (bl2wc c div 2) = bl2wc c - bl2wc c mod 2"
  4075 
  3937   "bl2wc (Oc # list) mod 2 = Suc 0" 
  4076 lemma [simp]: "bl2wc [Oc] = Suc 0"
  3938   by(cases c;cases "hd c";force simp: bl2wc.simps bl2nat.simps bl2nat_double)+
  4077  by(simp add: bl2wc.simps bl2nat.simps)
       
  4078 
       
  4079 lemma [simp]: "b \<noteq> [] \<Longrightarrow> bl2wc (tl b) = bl2wc b div 2"
       
  4080 apply(case_tac b, simp, case_tac a)
       
  4081 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4082 done
       
  4083 
       
  4084 lemma [simp]: "b \<noteq> [] \<Longrightarrow> bl2wc ([hd b]) = bl2wc b mod 2"
       
  4085 apply(case_tac b, simp, case_tac a)
       
  4086 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4087 done
       
  4088 
       
  4089 lemma [simp]: "\<lbrakk>b \<noteq> []\<rbrakk> \<Longrightarrow> bl2wc (hd b # c) = 2 * bl2wc c + bl2wc b mod 2"
       
  4090 apply(case_tac b, simp, case_tac a)
       
  4091 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4092 done
       
  4093 
       
  4094 lemma [simp]: " 2 * (bl2wc c div 2) = bl2wc c - bl2wc c mod 2" 
       
  4095   by(simp add: mult_div_cancel)
       
  4096 
       
  4097 lemma [simp]: "bl2wc (Oc # list) mod 2 = Suc 0" 
       
  4098   by(simp add: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4099 
       
  4100 
  3939 
  4101 declare code.simps[simp del]
  3940 declare code.simps[simp del]
  4102 declare nth_of.simps[simp del]
  3941 declare nth_of.simps[simp del]
  4103 
  3942 
  4104 text {*
  3943 text {*
  4134     apply(auto simp: trpl_code.simps 
  3973     apply(auto simp: trpl_code.simps 
  4135          newleft.simps newrght.simps split: action.splits)
  3974          newleft.simps newrght.simps split: action.splits)
  4136     done
  3975     done
  4137 qed
  3976 qed
  4138 
  3977 
  4139 lemma [simp]: "bl2nat (Oc # Oc\<up>x) 0 = (2 * 2 ^ x - Suc 0)"
  3978 lemma bl2nat_simps[simp]: "bl2nat (Oc # Oc\<up>x) 0 = (2 * 2 ^ x - Suc 0)"
  4140 apply(induct x)
  3979   "bl2nat (Bk\<up>x) n = 0"
  4141 apply(simp add: bl2nat.simps)
  3980  by(induct x;force simp: bl2nat.simps bl2nat_double exp_ind)+
  4142 apply(simp add: bl2nat.simps bl2nat_double exp_ind)
  3981 
  4143 done
  3982 lemma bl2nat_exp_zero[simp]: "bl2nat (Oc\<up>y) 0 = 2^y - Suc 0"
  4144 
       
  4145 lemma [simp]: "bl2nat (Oc\<up>y) 0 = 2^y - Suc 0"
       
  4146 apply(induct y, auto simp: bl2nat.simps bl2nat_double)
  3983 apply(induct y, auto simp: bl2nat.simps bl2nat_double)
  4147 apply(case_tac "(2::nat)^y", auto)
  3984 apply(case_tac "(2::nat)^y", auto)
  4148 done
       
  4149 
       
  4150 lemma [simp]: "bl2nat (Bk\<up>l) n = 0"
       
  4151 apply(induct l, auto simp: bl2nat.simps bl2nat_double exp_ind)
       
  4152 done
  3985 done
  4153 
  3986 
  4154 lemma bl2nat_cons_bk: "bl2nat (ks @ [Bk]) 0 = bl2nat ks 0"
  3987 lemma bl2nat_cons_bk: "bl2nat (ks @ [Bk]) 0 = bl2nat ks 0"
  4155 apply(induct ks, auto simp: bl2nat.simps)
  3988 apply(induct ks, auto simp: bl2nat.simps)
  4156 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double)
  3989 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double)
  4198 by auto
  4031 by auto
  4199 
  4032 
  4200 lemma tape_of_nat_list_butlast_last:
  4033 lemma tape_of_nat_list_butlast_last:
  4201   "ys \<noteq> [] \<Longrightarrow> <ys @ [y]> = <ys> @ Bk # Oc\<up>Suc y"
  4034   "ys \<noteq> [] \<Longrightarrow> <ys @ [y]> = <ys> @ Bk # Oc\<up>Suc y"
  4202 apply(induct ys, simp, simp)
  4035 apply(induct ys, simp, simp)
  4203 apply(case_tac "ys = []", simp add: tape_of_nl_abv tape_of_nat_abv
  4036 apply(case_tac "ys = []", simp add: tape_of_list_def tape_of_nat_def)
  4204                                     tape_of_nat_list.simps)
  4037 apply(simp add: tape_of_nl_cons tape_of_nat_def)
  4205 apply(simp add: tape_of_nl_cons tape_of_nat_abv)
       
  4206 done
  4038 done
  4207 
  4039 
  4208 lemma listsum2_append:
  4040 lemma listsum2_append:
  4209   "\<lbrakk>n \<le> length xs\<rbrakk> \<Longrightarrow> listsum2 (xs @ ys) n = listsum2 xs n"
  4041   "\<lbrakk>n \<le> length xs\<rbrakk> \<Longrightarrow> listsum2 (xs @ ys) n = listsum2 xs n"
  4210 apply(induct n)
  4042 apply(induct n)
  4242     apply(rule_tac ind, simp)
  4074     apply(rule_tac ind, simp)
  4243     done
  4075     done
  4244   thus "length (<xs @ [x]>) =
  4076   thus "length (<xs @ [x]>) =
  4245     Suc (listsum2 (map Suc xs @ [Suc x]) (length xs) + x + length xs)"
  4077     Suc (listsum2 (map Suc xs @ [Suc x]) (length xs) + x + length xs)"
  4246     apply(case_tac "xs = []")
  4078     apply(case_tac "xs = []")
  4247     apply(simp add: tape_of_nl_abv listsum2.simps 
  4079     apply(simp add: tape_of_list_def listsum2.simps 
  4248       tape_of_nat_list.simps tape_of_nat_abv)
  4080       tape_of_nat_list.simps tape_of_nat_def)
  4249     apply(simp add: tape_of_nat_list_butlast_last)
  4081     apply(simp add: tape_of_nat_list_butlast_last)
  4250     using listsum2_append[of "length xs" "map Suc xs" "[Suc x]"]
  4082     using listsum2_append[of "length xs" "map Suc xs" "[Suc x]"]
  4251     apply(simp)
  4083     apply(simp)
  4252     done
  4084     done
  4253 next
  4085 next
  4265               listsum2 (map Suc ys) (length ys) + length ys - 1"
  4097               listsum2 (map Suc ys) (length ys) + length ys - 1"
  4266   using length_listsum2_eq[of ys "length ys"]
  4098   using length_listsum2_eq[of ys "length ys"]
  4267   apply(simp)
  4099   apply(simp)
  4268   done
  4100   done
  4269 
  4101 
  4270 lemma [simp]:
  4102 lemma trpl_code_simp[simp]:
  4271  "trpl_code (steps0 (Suc 0, Bk\<up>l, <lm>) tp 0) = 
  4103  "trpl_code (steps0 (Suc 0, Bk\<up>l, <lm>) tp 0) = 
  4272     rec_exec rec_conf [code tp, bl2wc (<lm>), 0]"
  4104     rec_exec rec_conf [code tp, bl2wc (<lm>), 0]"
  4273 apply(simp add: steps.simps rec_exec.simps conf_lemma  conf.simps 
  4105 apply(simp add: steps.simps rec_exec.simps conf_lemma  conf.simps 
  4274                 inpt.simps trpl_code.simps bl2wc.simps)
  4106                 inpt.simps trpl_code.simps bl2wc.simps)
  4275 done
  4107 done
  4352         by(simp add: newconf_lemma)
  4184         by(simp add: newconf_lemma)
  4353     qed
  4185     qed
  4354   qed
  4186   qed
  4355 qed
  4187 qed
  4356 
  4188 
  4357 lemma [simp]: "bl2wc (Bk\<up> m) = 0"
  4189 lemma bl2wc_Bk_0[simp]: "bl2wc (Bk\<up> m) = 0"
  4358 apply(induct m)
  4190 apply(induct m)
  4359 apply(simp, simp)
  4191 apply(simp, simp)
  4360 done
  4192 done
  4361 
  4193 
  4362 lemma [simp]: "bl2wc (Oc\<up> rs@Bk\<up> n) = bl2wc (Oc\<up> rs)"
  4194 lemma bl2wc_Oc_then_Bk[simp]: "bl2wc (Oc\<up> rs@Bk\<up> n) = bl2wc (Oc\<up> rs)"
  4363 apply(induct rs, simp, 
  4195 apply(induct rs, simp, 
  4364   simp add: bl2wc.simps bl2nat.simps bl2nat_double)
  4196   simp add: bl2wc.simps bl2nat.simps bl2nat_double)
  4365 done
  4197 done
  4366 
  4198 
  4367 lemma lg_power: "x > Suc 0 \<Longrightarrow> lg (x ^ rs) x = rs"
  4199 lemma lg_power: "x > Suc 0 \<Longrightarrow> lg (x ^ rs) x = rs"
  4436       apply(case_tac rs, simp, simp add: bl2nat.simps)
  4268       apply(case_tac rs, simp, simp add: bl2nat.simps)
  4437       done
  4269       done
  4438   qed
  4270   qed
  4439 qed
  4271 qed
  4440 
  4272 
  4441 lemma [simp]: "actn m 0 r = 4"
  4273 lemma actn_0_is_4[simp]: "actn m 0 r = 4"
  4442 by(simp add: actn.simps)
  4274 by(simp add: actn.simps)
  4443 
  4275 
  4444 lemma [simp]: "newstat m 0 r = 0"
  4276 lemma newstat_0_0[simp]: "newstat m 0 r = 0"
  4445 by(simp add: newstat.simps)
  4277 by(simp add: newstat.simps)
  4446 
  4278 
  4447 declare step_red[simp del]
  4279 declare step_red[simp del]
  4448 
  4280 
  4449 lemma halt_least_step: 
  4281 lemma halt_least_step: 
  4534 apply(auto simp: nonstop.simps NSTD.simps split: if_splits)
  4366 apply(auto simp: nonstop.simps NSTD.simps split: if_splits)
  4535 using conf_trpl_ex[of m lm stpa]
  4367 using conf_trpl_ex[of m lm stpa]
  4536 apply(auto)
  4368 apply(auto)
  4537 done
  4369 done
  4538 
  4370 
  4539 lemma [elim]: "x > Suc 0 \<Longrightarrow> Max {u. x ^ u dvd x ^ r} = r"
  4371 lemma max_divisors: "x > Suc 0 \<Longrightarrow> Max {u. x ^ u dvd x ^ r} = r"
  4540 proof(rule_tac Max_eqI)
  4372 proof(rule_tac Max_eqI)
  4541   assume "x > Suc 0"
  4373   assume "x > Suc 0"
  4542   thus "finite {u. x ^ u dvd x ^ r}"
  4374   thus "finite {u. x ^ u dvd x ^ r}"
  4543     apply(rule_tac finite_power_dvd, auto)
  4375     apply(rule_tac finite_power_dvd, auto)
  4544     done
  4376     done
  4553     done
  4385     done
  4554 next
  4386 next
  4555   show "r \<in> {u. x ^ u dvd x ^ r}" by simp
  4387   show "r \<in> {u. x ^ u dvd x ^ r}" by simp
  4556 qed  
  4388 qed  
  4557 
  4389 
  4558 lemma lo_power: "x > Suc 0 \<Longrightarrow> lo (x ^ r) x = r"
  4390 lemma lo_power:
  4559 apply(auto simp: lo.simps loR.simps mod_dvd_simp)
  4391   assumes "x > Suc 0" shows "lo (x ^ r) x = r"
  4560 apply(case_tac "x^r", simp_all)
  4392 proof -
  4561 done
  4393   have "\<not> Suc 0 < x ^ r \<Longrightarrow> r = 0" using assms
       
  4394     by (metis Suc_lessD Suc_lessI nat_power_eq_Suc_0_iff zero_less_power)
       
  4395   moreover have "\<forall>xa. \<not> x ^ xa dvd x ^ r \<Longrightarrow> r = 0"
       
  4396     using dvd_refl assms by(cases "x^r";blast)
       
  4397   ultimately show ?thesis using assms
       
  4398     by(auto simp: lo.simps loR.simps mod_dvd_simp elim:max_divisors)
       
  4399 qed
  4562 
  4400 
  4563 lemma lo_rgt: "lo (trpl 0 0 r) (Pi 2) = r"
  4401 lemma lo_rgt: "lo (trpl 0 0 r) (Pi 2) = r"
  4564 apply(simp add: trpl.simps lo_power)
  4402 apply(simp add: trpl.simps lo_power)
  4565 done
  4403 done
  4566 
  4404