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