thys/Recursive.thy
changeset 248 aea02b5a58d2
parent 240 696081f445c2
child 285 447b433b67fa
equal deleted inserted replaced
247:89ed51d72e4a 248:aea02b5a58d2
     4 
     4 
     5 fun addition :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
     5 fun addition :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
     6   where
     6   where
     7   "addition m n p = [Dec m 4, Inc n, Inc p, Goto 0, Dec p 7, Inc m, Goto 4]"
     7   "addition m n p = [Dec m 4, Inc n, Inc p, Goto 0, Dec p 7, Inc m, Goto 4]"
     8 
     8 
     9 (* moves register m to register n *)
       
    10 fun mv_box :: "nat \<Rightarrow> nat \<Rightarrow> abc_prog"
     9 fun mv_box :: "nat \<Rightarrow> nat \<Rightarrow> abc_prog"
    11   where
    10   where
    12   "mv_box m n = [Dec m 3, Inc n, Goto 0]"
    11   "mv_box m n = [Dec m 3, Inc n, Goto 0]"
    13 
    12 
    14 text {* The compilation of @{text "z"}-operator. *}
    13 text {* The compilation of @{text "z"}-operator. *}
    17   "rec_ci_z \<equiv> [Goto 1]"
    16   "rec_ci_z \<equiv> [Goto 1]"
    18 
    17 
    19 text {* The compilation of @{text "s"}-operator. *}
    18 text {* The compilation of @{text "s"}-operator. *}
    20 definition rec_ci_s :: "abc_inst list"
    19 definition rec_ci_s :: "abc_inst list"
    21   where
    20   where
    22   "rec_ci_s \<equiv> addition 0 1 2 [+] [Inc 1]"
    21   "rec_ci_s \<equiv> (addition 0 1 2 [+] [Inc 1])"
    23 
    22 
    24 
    23 
    25 text {* The compilation of @{text "id i j"}-operator *}
    24 text {* The compilation of @{text "id i j"}-operator *}
    26 fun rec_ci_id :: "nat \<Rightarrow> nat \<Rightarrow> abc_inst list"
    25 fun rec_ci_id :: "nat \<Rightarrow> nat \<Rightarrow> abc_inst list"
    27   where
    26   where
    35 fun empty_boxes :: "nat \<Rightarrow> abc_inst list"
    34 fun empty_boxes :: "nat \<Rightarrow> abc_inst list"
    36   where
    35   where
    37   "empty_boxes 0 = []" |
    36   "empty_boxes 0 = []" |
    38   "empty_boxes (Suc n) = empty_boxes n [+] [Dec n 2, Goto 0]"
    37   "empty_boxes (Suc n) = empty_boxes n [+] [Dec n 2, Goto 0]"
    39 
    38 
    40 fun cn_merge_gs :: "(abc_inst list \<times> nat \<times> nat) list \<Rightarrow> nat \<Rightarrow> abc_inst list"
    39 fun cn_merge_gs ::
       
    40   "(abc_inst list \<times> nat \<times> nat) list \<Rightarrow> nat \<Rightarrow> abc_inst list"
    41   where
    41   where
    42   "cn_merge_gs [] p = []" |
    42   "cn_merge_gs [] p = []" |
    43   "cn_merge_gs (g # gs) p = 
    43   "cn_merge_gs (g # gs) p = 
    44       (let (gprog, gpara, gn) = g in 
    44       (let (gprog, gpara, gn) = g in 
    45          gprog [+] mv_box gpara p [+] cn_merge_gs gs (Suc p))"
    45          gprog [+] mv_box gpara p [+] cn_merge_gs gs (Suc p))"
    89         mv_box.simps[simp del] addition.simps[simp del]
    89         mv_box.simps[simp del] addition.simps[simp del]
    90   
    90   
    91 declare abc_steps_l.simps[simp del] abc_fetch.simps[simp del] 
    91 declare abc_steps_l.simps[simp del] abc_fetch.simps[simp del] 
    92         abc_step_l.simps[simp del] 
    92         abc_step_l.simps[simp del] 
    93 
    93 
    94 fun addition_inv :: "nat \<times> nat list \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> bool"
    94 inductive_cases terminate_pr_reverse: "terminate (Pr n f g) xs"
       
    95 
       
    96 inductive_cases terminate_z_reverse[elim!]: "terminate z xs"
       
    97 
       
    98 inductive_cases terminate_s_reverse[elim!]: "terminate s xs"
       
    99 
       
   100 inductive_cases terminate_id_reverse[elim!]: "terminate (id m n) xs"
       
   101 
       
   102 inductive_cases terminate_cn_reverse[elim!]: "terminate (Cn n f gs) xs"
       
   103 
       
   104 inductive_cases terminate_mn_reverse[elim!]:"terminate (Mn n f) xs"
       
   105 
       
   106 fun addition_inv :: "nat \<times> nat list \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow>     
       
   107                      nat list \<Rightarrow> bool"
    95   where
   108   where
    96   "addition_inv (as, lm') m n p lm = 
   109   "addition_inv (as, lm') m n p lm = 
    97         (let sn = lm ! n in
   110         (let sn = lm ! n in
    98          let sm = lm ! m in
   111          let sm = lm ! m in
    99          lm ! p = 0 \<and>
   112          lm ! p = 0 \<and>
   138               else if as = 5 then 2
   151               else if as = 5 then 2
   139               else if as = 6 then 1 
   152               else if as = 6 then 1 
   140               else if as = 4 then 0 
   153               else if as = 4 then 0 
   141               else 0)"
   154               else 0)"
   142 
   155 
   143 fun addition_measure :: "((nat \<times> nat list) \<times> nat \<times> nat) \<Rightarrow> (nat \<times> nat \<times> nat)"
   156 fun addition_measure :: "((nat \<times> nat list) \<times> nat \<times> nat) \<Rightarrow> 
       
   157                                                  (nat \<times> nat \<times> nat)"
   144   where
   158   where
   145   "addition_measure ((as, lm), m, p) =
   159   "addition_measure ((as, lm), m, p) =
   146      (addition_stage1 (as, lm) m p, 
   160      (addition_stage1 (as, lm) m p, 
   147       addition_stage2 (as, lm) m p,
   161       addition_stage2 (as, lm) m p,
   148       addition_stage3 (as, lm) m p)"
   162       addition_stage3 (as, lm) m p)"
   149 
   163 
   150 definition addition_LE :: "(((nat \<times> nat list) \<times> nat \<times> nat) \<times> ((nat \<times> nat list) \<times> nat \<times> nat)) set"
   164 definition addition_LE :: "(((nat \<times> nat list) \<times> nat \<times> nat) \<times> 
       
   165                           ((nat \<times> nat list) \<times> nat \<times> nat)) set"
   151   where "addition_LE \<equiv> (inv_image lex_triple addition_measure)"
   166   where "addition_LE \<equiv> (inv_image lex_triple addition_measure)"
   152 
   167 
   153 lemma [simp]: "wf addition_LE"
   168 lemma [simp]: "wf addition_LE"
   154 by(auto simp: wf_inv_image addition_LE_def lex_triple_def lex_pair_def)
   169 by(auto simp: wf_inv_image addition_LE_def lex_triple_def
       
   170              lex_pair_def)
   155 
   171 
   156 declare addition_inv.simps[simp del]
   172 declare addition_inv.simps[simp del]
   157 
   173 
   158 lemma addition_inv_init: 
   174 lemma addition_inv_init: 
   159   "\<lbrakk>m \<noteq> n; max m n < p; length lm > p; lm ! p = 0\<rbrakk> \<Longrightarrow>
   175   "\<lbrakk>m \<noteq> n; max m n < p; length lm > p; lm ! p = 0\<rbrakk> \<Longrightarrow>
   311     apply(auto)
   327     apply(auto)
   312     done
   328     done
   313 qed
   329 qed
   314 
   330 
   315 lemma compile_s_correct':
   331 lemma compile_s_correct':
   316   "{\<lambda>nl. nl = n # 0 \<up> 2 @ anything} 
   332   "{\<lambda>nl. nl = n # 0 \<up> 2 @ anything} addition 0 (Suc 0) 2 [+] [Inc (Suc 0)] {\<lambda>nl. nl = n # Suc n # 0 # anything}"
   317    addition 0 (Suc 0) 2 [+] [Inc (Suc 0)] 
       
   318    {\<lambda>nl. nl = n # Suc n # 0 # anything}"
       
   319 proof(rule_tac abc_Hoare_plus_halt)
   333 proof(rule_tac abc_Hoare_plus_halt)
   320   show "{\<lambda>nl. nl = n # 0 \<up> 2 @ anything} 
   334   show "{\<lambda>nl. nl = n # 0 \<up> 2 @ anything} addition 0 (Suc 0) 2 {\<lambda> nl. addition_inv (7, nl) 0 (Suc 0) 2 (n # 0 \<up> 2 @ anything)}"
   321         addition 0 (Suc 0) 2 
       
   322         {\<lambda>nl. addition_inv (7, nl) 0 (Suc 0) 2 (n # 0 \<up> 2 @ anything)}"
       
   323     by(rule_tac addition_correct, auto simp: numeral_2_eq_2)
   335     by(rule_tac addition_correct, auto simp: numeral_2_eq_2)
   324 next
   336 next
   325   show "{\<lambda>nl. addition_inv (7, nl) 0 (Suc 0) 2 (n # 0 \<up> 2 @ anything)} 
   337   show "{\<lambda>nl. addition_inv (7, nl) 0 (Suc 0) 2 (n # 0 \<up> 2 @ anything)} [Inc (Suc 0)] {\<lambda>nl. nl = n # Suc n # 0 # anything}"
   326         [Inc (Suc 0)] 
       
   327         {\<lambda>nl. nl = n # Suc n # 0 # anything}"
       
   328     by(rule_tac abc_Hoare_haltI, rule_tac x = 1 in exI, auto simp: addition_inv.simps 
   338     by(rule_tac abc_Hoare_haltI, rule_tac x = 1 in exI, auto simp: addition_inv.simps 
   329       abc_steps_l.simps abc_step_l.simps abc_fetch.simps numeral_2_eq_2 abc_lm_s.simps abc_lm_v.simps)
   339       abc_steps_l.simps abc_step_l.simps abc_fetch.simps numeral_2_eq_2 abc_lm_s.simps abc_lm_v.simps)
   330 qed
   340 qed
   331   
   341   
   332 declare rec_eval.simps[simp del]
   342 declare rec_exec.simps[simp del]
   333 
   343 
   334 lemma abc_comp_commute: "(A [+] B) [+] C = A [+] (B [+] C)"
   344 lemma abc_comp_commute: "(A [+] B) [+] C = A [+] (B [+] C)"
   335 apply(auto simp: abc_comp.simps abc_shift.simps)
   345 apply(auto simp: abc_comp.simps abc_shift.simps)
   336 apply(case_tac x, auto)
   346 apply(case_tac x, auto)
   337 done
   347 done
   338 
   348 
   339 
   349 
   340 
   350 
   341 lemma compile_z_correct: 
   351 lemma compile_z_correct: 
   342   "\<lbrakk>rec_ci z = (ap, arity, fp); rec_eval z [n] = r\<rbrakk> \<Longrightarrow> 
   352   "\<lbrakk>rec_ci z = (ap, arity, fp); rec_exec z [n] = r\<rbrakk> \<Longrightarrow> 
   343   {\<lambda>nl. nl = n # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = n # r # 0 \<up> (fp - Suc arity) @ anything}"
   353   {\<lambda>nl. nl = n # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = n # r # 0 \<up> (fp - Suc arity) @ anything}"
   344 apply(rule_tac abc_Hoare_haltI)
   354 apply(rule_tac abc_Hoare_haltI)
   345 apply(rule_tac x = 1 in exI)
   355 apply(rule_tac x = 1 in exI)
   346 apply(auto simp: abc_steps_l.simps rec_ci.simps rec_ci_z_def 
   356 apply(auto simp: abc_steps_l.simps rec_ci.simps rec_ci_z_def 
   347                  numeral_2_eq_2 abc_fetch.simps abc_step_l.simps rec_eval.simps)
   357                  numeral_2_eq_2 abc_fetch.simps abc_step_l.simps rec_exec.simps)
   348 done
   358 done
   349 
   359 
   350 lemma compile_s_correct: 
   360 lemma compile_s_correct: 
   351   "\<lbrakk>rec_ci s = (ap, arity, fp); rec_eval s [n] = r\<rbrakk> \<Longrightarrow> 
   361   "\<lbrakk>rec_ci s = (ap, arity, fp); rec_exec s [n] = r\<rbrakk> \<Longrightarrow> 
   352   {\<lambda>nl. nl = n # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = n # r # 0 \<up> (fp - Suc arity) @ anything}"
   362   {\<lambda>nl. nl = n # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = n # r # 0 \<up> (fp - Suc arity) @ anything}"
   353 apply(auto simp: rec_ci.simps rec_ci_s_def compile_s_correct' rec_eval.simps)
   363 apply(auto simp: rec_ci.simps rec_ci_s_def compile_s_correct' rec_exec.simps)
   354 done
   364 done
   355 
   365 
   356 lemma compile_id_correct':
   366 lemma compile_id_correct':
   357   assumes "n < length args" 
   367   assumes "n < length args" 
   358   shows "{\<lambda>nl. nl = args @ 0 \<up> 2 @ anything} addition n (length args) (Suc (length args))
   368   shows "{\<lambda>nl. nl = args @ 0 \<up> 2 @ anything} addition n (length args) (Suc (length args))
   359   {\<lambda>nl. nl = args @ rec_eval (recf.id (length args) n) args # 0 # anything}"
   369   {\<lambda>nl. nl = args @ rec_exec (recf.id (length args) n) args # 0 # anything}"
   360 proof -
   370 proof -
   361   have "{\<lambda>nl. nl = args @ 0 \<up> 2 @ anything} addition n (length args) (Suc (length args))
   371   have "{\<lambda>nl. nl = args @ 0 \<up> 2 @ anything} addition n (length args) (Suc (length args))
   362   {\<lambda>nl. addition_inv (7, nl) n (length args) (Suc (length args)) (args @ 0 \<up> 2 @ anything)}"
   372   {\<lambda>nl. addition_inv (7, nl) n (length args) (Suc (length args)) (args @ 0 \<up> 2 @ anything)}"
   363     using assms
   373     using assms
   364     by(rule_tac addition_correct, auto simp: numeral_2_eq_2 nth_append)
   374     by(rule_tac addition_correct, auto simp: numeral_2_eq_2 nth_append)
   365   thus "?thesis"
   375   thus "?thesis"
   366     using assms
   376     using assms
   367     by(simp add: addition_inv.simps rec_eval.simps 
   377     by(simp add: addition_inv.simps rec_exec.simps 
   368       nth_append numeral_2_eq_2 list_update_append)
   378       nth_append numeral_2_eq_2 list_update_append)
   369 qed
   379 qed
   370 
   380 
   371 lemma compile_id_correct: 
   381 lemma compile_id_correct: 
   372   "\<lbrakk>n < m; length xs = m; rec_ci (recf.id m n) = (ap, arity, fp); rec_eval (recf.id m n) xs = r\<rbrakk>
   382   "\<lbrakk>n < m; length xs = m; rec_ci (recf.id m n) = (ap, arity, fp); rec_exec (recf.id m n) xs = r\<rbrakk>
   373        \<Longrightarrow> {\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ r # 0 \<up> (fp - Suc arity) @ anything}"
   383        \<Longrightarrow> {\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ r # 0 \<up> (fp - Suc arity) @ anything}"
   374 apply(auto simp: rec_ci.simps rec_ci_id.simps compile_id_correct')
   384 apply(auto simp: rec_ci.simps rec_ci_id.simps compile_id_correct')
   375 done
   385 done
   376 
   386 
   377 lemma cn_merge_gs_tl_app: 
   387 lemma cn_merge_gs_tl_app: 
   389 apply(case_tac "rec_ci a1", case_tac "rec_ci a2", auto)
   399 apply(case_tac "rec_ci a1", case_tac "rec_ci a2", auto)
   390 apply(case_tac "rec_ci a", auto)
   400 apply(case_tac "rec_ci a", auto)
   391 done
   401 done
   392 
   402 
   393 lemma param_pattern: 
   403 lemma param_pattern: 
   394   "\<lbrakk>terminates f xs; rec_ci f = (p, arity, fp)\<rbrakk> \<Longrightarrow> length xs = arity"
   404   "\<lbrakk>terminate f xs; rec_ci f = (p, arity, fp)\<rbrakk> \<Longrightarrow> length xs = arity"
   395 apply(induct arbitrary: p arity fp rule: terminates.induct)
   405 apply(induct arbitrary: p arity fp rule: terminate.induct)
   396 apply(auto simp: rec_ci.simps)
   406 apply(auto simp: rec_ci.simps)
   397 apply(case_tac "rec_ci f", simp)
   407 apply(case_tac "rec_ci f", simp)
   398 apply(case_tac "rec_ci f", case_tac "rec_ci g", simp)
   408 apply(case_tac "rec_ci f", case_tac "rec_ci g", simp)
   399 apply(case_tac "rec_ci f", case_tac "rec_ci gs", simp)
   409 apply(case_tac "rec_ci f", case_tac "rec_ci gs", simp)
   400 done
   410 done
   588 
   598 
   589 declare list_update.simps(2)[simp del]
   599 declare list_update.simps(2)[simp del]
   590 
   600 
   591 lemma [simp]:
   601 lemma [simp]:
   592   "\<lbrakk>length xs < gf; gf \<le> ft; n < length gs\<rbrakk>
   602   "\<lbrakk>length xs < gf; gf \<le> ft; n < length gs\<rbrakk>
   593   \<Longrightarrow> (rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything)
   603   \<Longrightarrow> (rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything)
   594   [ft + n - length xs := rec_eval (gs ! n) xs, 0 := 0] =
   604   [ft + n - length xs := rec_exec (gs ! n) xs, 0 := 0] =
   595   0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ rec_eval (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything"
   605   0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ rec_exec (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything"
   596 using list_update_append[of "rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_eval i xs) (take n gs)"
   606 using list_update_append[of "rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_exec i xs) (take n gs)"
   597                              "0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything" "ft + n - length xs" "rec_eval (gs ! n) xs"]
   607                              "0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything" "ft + n - length xs" "rec_exec (gs ! n) xs"]
   598 apply(auto)
   608 apply(auto)
   599 apply(case_tac "length gs - n", simp, simp add: list_update.simps replicate_Suc_iff_anywhere Suc_diff_Suc del: replicate_Suc)
   609 apply(case_tac "length gs - n", simp, simp add: list_update.simps replicate_Suc_iff_anywhere Suc_diff_Suc del: replicate_Suc)
   600 apply(simp add: list_update.simps)
   610 apply(simp add: list_update.simps)
   601 done
   611 done
   602 
   612 
   603 lemma compile_cn_gs_correct':
   613 lemma compile_cn_gs_correct':
   604   assumes
   614   assumes
   605   g_cond: "\<forall>g\<in>set (take n gs). terminates g xs \<and>
   615   g_cond: "\<forall>g\<in>set (take n gs). terminate g xs \<and>
   606   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_eval g xs # 0 \<up> (xb - Suc xa) @ xc}))"
   616   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_exec g xs # 0 \<up> (xb - Suc xa) @ xc}))"
   607   and ft: "ft = max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   617   and ft: "ft = max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   608   shows 
   618   shows 
   609   "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   619   "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   610     cn_merge_gs (map rec_ci (take n gs)) ft
   620     cn_merge_gs (map rec_ci (take n gs)) ft
   611   {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @
   621   {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @
   612                     map (\<lambda>i. rec_eval i xs) (take n gs) @ 0\<up>(length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   622                     map (\<lambda>i. rec_exec i xs) (take n gs) @ 0\<up>(length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   613   using g_cond
   623   using g_cond
   614 proof(induct n)
   624 proof(induct n)
   615   case 0
   625   case 0
   616   have "ft > length xs"
   626   have "ft > length xs"
   617     using ft
   627     using ft
   622       replicate_Suc[THEN sym] del: replicate_Suc)
   632       replicate_Suc[THEN sym] del: replicate_Suc)
   623     done
   633     done
   624 next
   634 next
   625   case (Suc n)
   635   case (Suc n)
   626   have ind': "\<forall>g\<in>set (take n gs).
   636   have ind': "\<forall>g\<in>set (take n gs).
   627      terminates g xs \<and> (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> 
   637      terminate g xs \<and> (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> 
   628     (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_eval g xs # 0 \<up> (xb - Suc xa) @ xc})) \<Longrightarrow>
   638     (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_exec g xs # 0 \<up> (xb - Suc xa) @ xc})) \<Longrightarrow>
   629     {\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci (take n gs)) ft 
   639     {\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci (take n gs)) ft 
   630     {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   640     {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   631     by fact
   641     by fact
   632   have g_newcond: "\<forall>g\<in>set (take (Suc n) gs).
   642   have g_newcond: "\<forall>g\<in>set (take (Suc n) gs).
   633      terminates g xs \<and> (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_eval g xs # 0 \<up> (xb - Suc xa) @ xc}))"
   643      terminate g xs \<and> (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_exec g xs # 0 \<up> (xb - Suc xa) @ xc}))"
   634     by fact
   644     by fact
   635   from g_newcond have ind:
   645   from g_newcond have ind:
   636     "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci (take n gs)) ft 
   646     "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci (take n gs)) ft 
   637     {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   647     {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   638     apply(rule_tac ind', rule_tac ballI, erule_tac x = g in ballE, simp_all add: take_Suc)
   648     apply(rule_tac ind', rule_tac ballI, erule_tac x = g in ballE, simp_all add: take_Suc)
   639     by(case_tac "n < length gs", simp add:take_Suc_conv_app_nth, simp)    
   649     by(case_tac "n < length gs", simp add:take_Suc_conv_app_nth, simp)    
   640   show "?case"
   650   show "?case"
   641   proof(cases "n < length gs")
   651   proof(cases "n < length gs")
   642     case True
   652     case True
   648       moreover have "min (length gs) n = n"
   658       moreover have "min (length gs) n = n"
   649         using h by simp
   659         using h by simp
   650       moreover have 
   660       moreover have 
   651         "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   661         "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   652         cn_merge_gs (map rec_ci (take n gs)) ft [+] (gp [+] mv_box ga (ft + n))
   662         cn_merge_gs (map rec_ci (take n gs)) ft [+] (gp [+] mv_box ga (ft + n))
   653         {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 
   663         {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 
   654         rec_eval (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   664         rec_exec (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   655       proof(rule_tac abc_Hoare_plus_halt)
   665       proof(rule_tac abc_Hoare_plus_halt)
   656         show "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci (take n gs)) ft
   666         show "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci (take n gs)) ft
   657           {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   667           {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything}"
   658           using ind by simp
   668           using ind by simp
   659       next
   669       next
   660         have x: "gs!n \<in> set (take (Suc n) gs)"
   670         have x: "gs!n \<in> set (take (Suc n) gs)"
   661           using h
   671           using h
   662           by(simp add: take_Suc_conv_app_nth)
   672           by(simp add: take_Suc_conv_app_nth)
   663         have b: "terminates (gs!n) xs"
   673         have b: "terminate (gs!n) xs"
   664           using a g_newcond h x
   674           using a g_newcond h x
   665           by(erule_tac x = "gs!n" in ballE, simp_all)
   675           by(erule_tac x = "gs!n" in ballE, simp_all)
   666         hence c: "length xs = ga"
   676         hence c: "length xs = ga"
   667           using a param_pattern by metis  
   677           using a param_pattern by metis  
   668         have d: "gf > ga" using footprint_ge a by simp
   678         have d: "gf > ga" using footprint_ge a by simp
   670           by(simp,  rule_tac min_max.le_supI2, rule_tac Max_ge, simp, 
   680           by(simp,  rule_tac min_max.le_supI2, rule_tac Max_ge, simp, 
   671             rule_tac insertI2,  
   681             rule_tac insertI2,  
   672             rule_tac f = "(\<lambda>(aprog, p, n). n)" and x = "rec_ci (gs!n)" in image_eqI, simp, 
   682             rule_tac f = "(\<lambda>(aprog, p, n). n)" and x = "rec_ci (gs!n)" in image_eqI, simp, 
   673             rule_tac x = "gs!n" in image_eqI, simp, simp)
   683             rule_tac x = "gs!n" in image_eqI, simp, simp)
   674         show "{\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ 
   684         show "{\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ 
   675           map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything} gp [+] mv_box ga (ft + n)
   685           map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything} gp [+] mv_box ga (ft + n)
   676           {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) 
   686           {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) 
   677           (take n gs) @ rec_eval (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   687           (take n gs) @ rec_exec (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   678         proof(rule_tac abc_Hoare_plus_halt)
   688         proof(rule_tac abc_Hoare_plus_halt)
   679           show "{\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything} gp 
   689           show "{\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything} gp 
   680                 {\<lambda>nl. nl = xs @ (rec_eval (gs!n) xs) # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_eval i xs) 
   690                 {\<lambda>nl. nl = xs @ (rec_exec (gs!n) xs) # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_exec i xs) 
   681                               (take n gs) @  0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything}"
   691                               (take n gs) @  0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything}"
   682           proof -
   692           proof -
   683             have 
   693             have 
   684               "({\<lambda>nl. nl = xs @ 0 \<up> (gf - ga) @ 0\<up>(ft - gf)@map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything} 
   694               "({\<lambda>nl. nl = xs @ 0 \<up> (gf - ga) @ 0\<up>(ft - gf)@map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything} 
   685             gp {\<lambda>nl. nl = xs @ (rec_eval (gs!n) xs) # 0 \<up> (gf - Suc ga) @ 
   695             gp {\<lambda>nl. nl = xs @ (rec_exec (gs!n) xs) # 0 \<up> (gf - Suc ga) @ 
   686               0\<up>(ft - gf)@map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything})"
   696               0\<up>(ft - gf)@map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 \<up> Suc (length xs) @ anything})"
   687               using a g_newcond h x
   697               using a g_newcond h x
   688               apply(erule_tac x = "gs!n" in ballE)
   698               apply(erule_tac x = "gs!n" in ballE)
   689               apply(simp, simp)
   699               apply(simp, simp)
   690               done            
   700               done            
   691             thus "?thesis"
   701             thus "?thesis"
   692               using a b c d e
   702               using a b c d e
   693               by(simp add: replicate_merge_anywhere)
   703               by(simp add: replicate_merge_anywhere)
   694           qed
   704           qed
   695         next
   705         next
   696           show 
   706           show 
   697             "{\<lambda>nl. nl = xs @ rec_eval (gs ! n) xs #
   707             "{\<lambda>nl. nl = xs @ rec_exec (gs ! n) xs #
   698             0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything}
   708             0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything}
   699             mv_box ga (ft + n)
   709             mv_box ga (ft + n)
   700             {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @
   710             {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @
   701             rec_eval (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   711             rec_exec (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   702           proof -
   712           proof -
   703             have "{\<lambda>nl. nl = xs @ rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @
   713             have "{\<lambda>nl. nl = xs @ rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @
   704               map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything}
   714               map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything}
   705               mv_box ga (ft + n) {\<lambda>nl. nl = (xs @ rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @
   715               mv_box ga (ft + n) {\<lambda>nl. nl = (xs @ rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @
   706               map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything)
   716               map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything)
   707               [ft + n := (xs @ rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 
   717               [ft + n := (xs @ rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 
   708               0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) ! ga +
   718               0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) ! ga +
   709               (xs @ rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ 
   719               (xs @ rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ 
   710               map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) !
   720               map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) !
   711                       (ft + n),  ga := 0]}"
   721                       (ft + n),  ga := 0]}"
   712               using a c d e h
   722               using a c d e h
   713               apply(rule_tac mv_box_correct)
   723               apply(rule_tac mv_box_correct)
   714               apply(simp, arith, arith)
   724               apply(simp, arith, arith)
   715               done
   725               done
   716             moreover have "(xs @ rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @
   726             moreover have "(xs @ rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @
   717               map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything)
   727               map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything)
   718               [ft + n := (xs @ rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ 
   728               [ft + n := (xs @ rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ 
   719               0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) ! ga +
   729               0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) ! ga +
   720               (xs @ rec_eval (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ 
   730               (xs @ rec_exec (gs ! n) xs # 0 \<up> (ft - Suc (length xs)) @ 
   721               map (\<lambda>i. rec_eval i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) !
   731               map (\<lambda>i. rec_exec i xs) (take n gs) @ 0 \<up> (length gs - n) @ 0 # 0 \<up> length xs @ anything) !
   722                       (ft + n),  ga := 0]= 
   732                       (ft + n),  ga := 0]= 
   723               xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ rec_eval (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything"
   733               xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ rec_exec (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything"
   724               using a c d e h
   734               using a c d e h
   725               by(simp add: list_update_append nth_append length_replicate split: if_splits del: list_update.simps(2), auto)
   735               by(simp add: list_update_append nth_append length_replicate split: if_splits del: list_update.simps(2), auto)
   726             ultimately show "?thesis"
   736             ultimately show "?thesis"
   727               by(simp)
   737               by(simp)
   728           qed
   738           qed
   730       qed
   740       qed
   731       ultimately show 
   741       ultimately show 
   732         "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   742         "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   733         cn_merge_gs (map rec_ci (take n gs)) ft [+] (case rec_ci (gs ! n) of (gprog, gpara, gn) \<Rightarrow>
   743         cn_merge_gs (map rec_ci (take n gs)) ft [+] (case rec_ci (gs ! n) of (gprog, gpara, gn) \<Rightarrow>
   734         gprog [+] mv_box gpara (ft + min (length gs) n))
   744         gprog [+] mv_box gpara (ft + min (length gs) n))
   735         {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) (take n gs) @ rec_eval (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   745         {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) (take n gs) @ rec_exec (gs ! n) xs # 0 \<up> (length gs - Suc n) @ 0 # 0 \<up> length xs @ anything}"
   736         by simp
   746         by simp
   737     qed
   747     qed
   738   next
   748   next
   739     case False
   749     case False
   740     have h: "\<not> n < length gs" by fact
   750     have h: "\<not> n < length gs" by fact
   741     hence ind': 
   751     hence ind': 
   742       "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci gs) ft
   752       "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything} cn_merge_gs (map rec_ci gs) ft
   743         {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_eval i xs) gs @ 0 \<up> Suc (length xs) @ anything}"
   753         {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @ map (\<lambda>i. rec_exec i xs) gs @ 0 \<up> Suc (length xs) @ anything}"
   744       using ind
   754       using ind
   745       by simp
   755       by simp
   746     thus "?thesis"
   756     thus "?thesis"
   747       using h
   757       using h
   748       by(simp)
   758       by(simp)
   749   qed
   759   qed
   750 qed
   760 qed
   751     
   761     
   752 lemma compile_cn_gs_correct:
   762 lemma compile_cn_gs_correct:
   753   assumes
   763   assumes
   754   g_cond: "\<forall>g\<in>set gs. terminates g xs \<and>
   764   g_cond: "\<forall>g\<in>set gs. terminate g xs \<and>
   755   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_eval g xs # 0 \<up> (xb - Suc xa) @ xc}))"
   765   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_exec g xs # 0 \<up> (xb - Suc xa) @ xc}))"
   756   and ft: "ft = max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   766   and ft: "ft = max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   757   shows 
   767   shows 
   758   "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   768   "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (ft + length gs) @ anything}
   759     cn_merge_gs (map rec_ci gs) ft
   769     cn_merge_gs (map rec_ci gs) ft
   760   {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @
   770   {\<lambda>nl. nl = xs @ 0 \<up> (ft - length xs) @
   761                     map (\<lambda>i. rec_eval i xs) gs @ 0 \<up> Suc (length xs) @ anything}"
   771                     map (\<lambda>i. rec_exec i xs) gs @ 0 \<up> Suc (length xs) @ anything}"
   762 using assms
   772 using assms
   763 using compile_cn_gs_correct'[of "length gs" gs xs ft ffp anything ]
   773 using compile_cn_gs_correct'[of "length gs" gs xs ft ffp anything ]
   764 apply(auto)
   774 apply(auto)
   765 done
   775 done
   766   
   776   
   955    by(simp add: mv_boxes.simps)
   965    by(simp add: mv_boxes.simps)
   956 qed    
   966 qed    
   957      
   967      
   958 lemma save_paras: 
   968 lemma save_paras: 
   959   "{\<lambda>nl. nl = xs @ 0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length xs) @
   969   "{\<lambda>nl. nl = xs @ 0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length xs) @
   960   map (\<lambda>i. rec_eval i xs) gs @ 0 \<up> Suc (length xs) @ anything}
   970   map (\<lambda>i. rec_exec i xs) gs @ 0 \<up> Suc (length xs) @ anything}
   961   mv_boxes 0 (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) (length xs)
   971   mv_boxes 0 (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) (length xs)
   962   {\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ map (\<lambda>i. rec_eval i xs) gs @ 0 # xs @ anything}"
   972   {\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ map (\<lambda>i. rec_exec i xs) gs @ 0 # xs @ anything}"
   963 proof -
   973 proof -
   964   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   974   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   965   have "{\<lambda>nl. nl = [] @ xs @ (0\<up>(?ft - length xs) @  map (\<lambda>i. rec_eval i xs) gs @ [0]) @ 
   975   have "{\<lambda>nl. nl = [] @ xs @ (0\<up>(?ft - length xs) @  map (\<lambda>i. rec_exec i xs) gs @ [0]) @ 
   966           0 \<up> (length xs) @ anything} mv_boxes 0 (Suc ?ft + length gs) (length xs) 
   976           0 \<up> (length xs) @ anything} mv_boxes 0 (Suc ?ft + length gs) (length xs) 
   967         {\<lambda>nl. nl = [] @ 0 \<up> (length xs) @ (0\<up>(?ft - length xs) @  map (\<lambda>i. rec_eval i xs) gs @ [0]) @ xs @ anything}"
   977         {\<lambda>nl. nl = [] @ 0 \<up> (length xs) @ (0\<up>(?ft - length xs) @  map (\<lambda>i. rec_exec i xs) gs @ [0]) @ xs @ anything}"
   968     by(rule_tac mv_boxes_correct, auto)
   978     by(rule_tac mv_boxes_correct, auto)
   969   thus "?thesis"
   979   thus "?thesis"
   970     by(simp add: replicate_merge_anywhere)
   980     by(simp add: replicate_merge_anywhere)
   971 qed
   981 qed
   972 
   982 
   976  apply(simp add: Max_ge_iff)
   986  apply(simp add: Max_ge_iff)
   977 done
   987 done
   978 
   988 
   979 lemma restore_new_paras:
   989 lemma restore_new_paras:
   980   "ffp \<ge> length gs 
   990   "ffp \<ge> length gs 
   981  \<Longrightarrow> {\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ map (\<lambda>i. rec_eval i xs) gs @ 0 # xs @ anything}
   991  \<Longrightarrow> {\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ map (\<lambda>i. rec_exec i xs) gs @ 0 # xs @ anything}
   982     mv_boxes (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) 0 (length gs)
   992     mv_boxes (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) 0 (length gs)
   983   {\<lambda>nl. nl = map (\<lambda>i. rec_eval i xs) gs @ 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ 0 # xs @ anything}"
   993   {\<lambda>nl. nl = map (\<lambda>i. rec_exec i xs) gs @ 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ 0 # xs @ anything}"
   984 proof -
   994 proof -
   985   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   995   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
   986   assume j: "ffp \<ge> length gs"
   996   assume j: "ffp \<ge> length gs"
   987   hence "{\<lambda> nl. nl = [] @ 0\<up>length gs @ 0\<up>(?ft - length gs) @  map (\<lambda>i. rec_eval i xs) gs @ ((0 # xs) @ anything)}
   997   hence "{\<lambda> nl. nl = [] @ 0\<up>length gs @ 0\<up>(?ft - length gs) @  map (\<lambda>i. rec_exec i xs) gs @ ((0 # xs) @ anything)}
   988        mv_boxes ?ft 0 (length gs)
   998        mv_boxes ?ft 0 (length gs)
   989         {\<lambda> nl. nl = [] @ map (\<lambda>i. rec_eval i xs) gs @ 0\<up>(?ft - length gs) @ 0\<up>length gs @ ((0 # xs) @ anything)}"
   999         {\<lambda> nl. nl = [] @ map (\<lambda>i. rec_exec i xs) gs @ 0\<up>(?ft - length gs) @ 0\<up>length gs @ ((0 # xs) @ anything)}"
   990     by(rule_tac mv_boxes_correct2, auto)
  1000     by(rule_tac mv_boxes_correct2, auto)
   991   moreover have "?ft \<ge> length gs"
  1001   moreover have "?ft \<ge> length gs"
   992     using j
  1002     using j
   993     by(auto)
  1003     by(auto)
   994   ultimately show "?thesis"
  1004   ultimately show "?thesis"
  1005 
  1015 
  1006 lemma save_rs:
  1016 lemma save_rs:
  1007   "\<lbrakk>far = length gs;
  1017   "\<lbrakk>far = length gs;
  1008   ffp \<le> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)));
  1018   ffp \<le> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)));
  1009   far < ffp\<rbrakk>
  1019   far < ffp\<rbrakk>
  1010 \<Longrightarrow>  {\<lambda>nl. nl = map (\<lambda>i. rec_eval i xs) gs @
  1020 \<Longrightarrow>  {\<lambda>nl. nl = map (\<lambda>i. rec_exec i xs) gs @
  1011   rec_eval (Cn (length xs) f gs) xs # 0 \<up> max (Suc (length xs))
  1021   rec_exec (Cn (length xs) f gs) xs # 0 \<up> max (Suc (length xs))
  1012   (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ xs @ anything}
  1022   (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ xs @ anything}
  1013     mv_box far (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))))
  1023     mv_box far (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))))
  1014     {\<lambda>nl. nl = map (\<lambda>i. rec_eval i xs) gs @
  1024     {\<lambda>nl. nl = map (\<lambda>i. rec_exec i xs) gs @
  1015                0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length gs) @
  1025                0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length gs) @
  1016                rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}"
  1026                rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}"
  1017 proof -
  1027 proof -
  1018   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1028   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1019   thm mv_box_correct
  1029   thm mv_box_correct
  1020   let ?lm= " map (\<lambda>i. rec_eval i xs) gs @ rec_eval (Cn (length xs) f gs) xs # 0 \<up> ?ft @ xs @ anything"
  1030   let ?lm= " map (\<lambda>i. rec_exec i xs) gs @ rec_exec (Cn (length xs) f gs) xs # 0 \<up> ?ft @ xs @ anything"
  1021   assume h: "far = length gs" "ffp \<le> ?ft" "far < ffp"
  1031   assume h: "far = length gs" "ffp \<le> ?ft" "far < ffp"
  1022   hence "{\<lambda> nl. nl = ?lm} mv_box far ?ft {\<lambda> nl. nl = ?lm[?ft := ?lm!far + ?lm!?ft, far := 0]}"
  1032   hence "{\<lambda> nl. nl = ?lm} mv_box far ?ft {\<lambda> nl. nl = ?lm[?ft := ?lm!far + ?lm!?ft, far := 0]}"
  1023     apply(rule_tac mv_box_correct)
  1033     apply(rule_tac mv_box_correct)
  1024     by(case_tac "rec_ci a", auto)  
  1034     by(case_tac "rec_ci a", auto)  
  1025   moreover have "?lm[?ft := ?lm!far + ?lm!?ft, far := 0]
  1035   moreover have "?lm[?ft := ?lm!far + ?lm!?ft, far := 0]
  1026     = map (\<lambda>i. rec_eval i xs) gs @
  1036     = map (\<lambda>i. rec_exec i xs) gs @
  1027     0 \<up> (?ft - length gs) @
  1037     0 \<up> (?ft - length gs) @
  1028     rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1038     rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1029     using h
  1039     using h
  1030     apply(simp add: nth_append)
  1040     apply(simp add: nth_append)
  1031     using list_update_length[of "map (\<lambda>i. rec_eval i xs) gs @ rec_eval (Cn (length xs) f gs) xs #
  1041     using list_update_length[of "map (\<lambda>i. rec_exec i xs) gs @ rec_exec (Cn (length xs) f gs) xs #
  1032        0 \<up> (?ft - Suc (length gs))" 0 "0 \<up> length gs @ xs @ anything" "rec_eval (Cn (length xs) f gs) xs"]
  1042        0 \<up> (?ft - Suc (length gs))" 0 "0 \<up> length gs @ xs @ anything" "rec_exec (Cn (length xs) f gs) xs"]
  1033     apply(simp add: replicate_merge_anywhere replicate_Suc_iff_anywhere del: replicate_Suc)
  1043     apply(simp add: replicate_merge_anywhere replicate_Suc_iff_anywhere del: replicate_Suc)
  1034     by(simp add: list_update_append list_update.simps replicate_Suc_iff_anywhere del: replicate_Suc)
  1044     by(simp add: list_update_append list_update.simps replicate_Suc_iff_anywhere del: replicate_Suc)
  1035   ultimately show "?thesis"
  1045   ultimately show "?thesis"
  1036     by(simp)
  1046     by(simp)
  1037 qed
  1047 qed
  1106 done
  1116 done
  1107 
  1117 
  1108 
  1118 
  1109 lemma clean_paras: 
  1119 lemma clean_paras: 
  1110   "ffp \<ge> length gs \<Longrightarrow>
  1120   "ffp \<ge> length gs \<Longrightarrow>
  1111   {\<lambda>nl. nl = map (\<lambda>i. rec_eval i xs) gs @
  1121   {\<lambda>nl. nl = map (\<lambda>i. rec_exec i xs) gs @
  1112   0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length gs) @
  1122   0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length gs) @
  1113   rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}
  1123   rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}
  1114   empty_boxes (length gs)
  1124   empty_boxes (length gs)
  1115   {\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ 
  1125   {\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ 
  1116   rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}"
  1126   rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}"
  1117 proof-
  1127 proof-
  1118   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1128   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1119   assume h: "length gs \<le> ffp"
  1129   assume h: "length gs \<le> ffp"
  1120   let ?lm = "map (\<lambda>i. rec_eval i xs) gs @ 0 \<up> (?ft - length gs) @
  1130   let ?lm = "map (\<lambda>i. rec_exec i xs) gs @ 0 \<up> (?ft - length gs) @
  1121     rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1131     rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1122   have "{\<lambda> nl. nl = ?lm} empty_boxes (length gs) {\<lambda> nl. nl = 0\<up>length gs @ drop (length gs) ?lm}"
  1132   have "{\<lambda> nl. nl = ?lm} empty_boxes (length gs) {\<lambda> nl. nl = 0\<up>length gs @ drop (length gs) ?lm}"
  1123     by(rule_tac empty_boxes_correct, simp)
  1133     by(rule_tac empty_boxes_correct, simp)
  1124   moreover have "0\<up>length gs @ drop (length gs) ?lm 
  1134   moreover have "0\<up>length gs @ drop (length gs) ?lm 
  1125            =  0 \<up> ?ft @  rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1135            =  0 \<up> ?ft @  rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1126     using h
  1136     using h
  1127     by(simp add: replicate_merge_anywhere)
  1137     by(simp add: replicate_merge_anywhere)
  1128   ultimately show "?thesis"
  1138   ultimately show "?thesis"
  1129     by metis
  1139     by metis
  1130 qed
  1140 qed
  1131  
  1141  
  1132 
  1142 
  1133 lemma restore_rs:
  1143 lemma restore_rs:
  1134   "{\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ 
  1144   "{\<lambda>nl. nl = 0 \<up> max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) @ 
  1135   rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}
  1145   rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything}
  1136   mv_box (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) (length xs)
  1146   mv_box (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) (length xs)
  1137   {\<lambda>nl. nl = 0 \<up> length xs @
  1147   {\<lambda>nl. nl = 0 \<up> length xs @
  1138   rec_eval (Cn (length xs) f gs) xs #
  1148   rec_exec (Cn (length xs) f gs) xs #
  1139   0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - (length xs)) @
  1149   0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - (length xs)) @
  1140   0 \<up> length gs @ xs @ anything}"
  1150   0 \<up> length gs @ xs @ anything}"
  1141 proof -
  1151 proof -
  1142   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1152   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1143   let ?lm = "0\<up>(length xs) @  0\<up>(?ft - (length xs)) @ rec_eval (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1153   let ?lm = "0\<up>(length xs) @  0\<up>(?ft - (length xs)) @ rec_exec (Cn (length xs) f gs) xs # 0 \<up> length gs @ xs @ anything"
  1144   thm mv_box_correct
  1154   thm mv_box_correct
  1145   have "{\<lambda> nl. nl = ?lm} mv_box ?ft (length xs) {\<lambda> nl. nl = ?lm[length xs := ?lm!?ft + ?lm!(length xs), ?ft := 0]}"
  1155   have "{\<lambda> nl. nl = ?lm} mv_box ?ft (length xs) {\<lambda> nl. nl = ?lm[length xs := ?lm!?ft + ?lm!(length xs), ?ft := 0]}"
  1146     by(rule_tac mv_box_correct, simp, simp)
  1156     by(rule_tac mv_box_correct, simp, simp)
  1147   moreover have "?lm[length xs := ?lm!?ft + ?lm!(length xs), ?ft := 0]
  1157   moreover have "?lm[length xs := ?lm!?ft + ?lm!(length xs), ?ft := 0]
  1148                =  0 \<up> length xs @ rec_eval (Cn (length xs) f gs) xs # 0 \<up> (?ft - (length xs)) @ 0 \<up> length gs @ xs @ anything"
  1158                =  0 \<up> length xs @ rec_exec (Cn (length xs) f gs) xs # 0 \<up> (?ft - (length xs)) @ 0 \<up> length gs @ xs @ anything"
  1149     apply(auto simp: list_update_append nth_append)
  1159     apply(auto simp: list_update_append nth_append)
  1150     apply(case_tac ?ft, simp_all add: Suc_diff_le list_update.simps)
  1160     apply(case_tac ?ft, simp_all add: Suc_diff_le list_update.simps)
  1151     apply(simp add: exp_suc replicate_Suc[THEN sym] del: replicate_Suc)
  1161     apply(simp add: exp_suc replicate_Suc[THEN sym] del: replicate_Suc)
  1152     done
  1162     done
  1153   ultimately show "?thesis"
  1163   ultimately show "?thesis"
  1154     by(simp add: replicate_merge_anywhere)
  1164     by(simp add: replicate_merge_anywhere)
  1155 qed
  1165 qed
  1156 
  1166 
  1157 lemma restore_orgin_paras:
  1167 lemma restore_orgin_paras:
  1158   "{\<lambda>nl. nl = 0 \<up> length xs @
  1168   "{\<lambda>nl. nl = 0 \<up> length xs @
  1159   rec_eval (Cn (length xs) f gs) xs #
  1169   rec_exec (Cn (length xs) f gs) xs #
  1160   0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length xs) @ 0 \<up> length gs @ xs @ anything}
  1170   0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) - length xs) @ 0 \<up> length gs @ xs @ anything}
  1161   mv_boxes (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) 0 (length xs)
  1171   mv_boxes (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) 0 (length xs)
  1162   {\<lambda>nl. nl = xs @ rec_eval (Cn (length xs) f gs) xs # 0 \<up> 
  1172   {\<lambda>nl. nl = xs @ rec_exec (Cn (length xs) f gs) xs # 0 \<up> 
  1163   (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs) @ anything}"
  1173   (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs) @ anything}"
  1164 proof -
  1174 proof -
  1165   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1175   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1166   thm mv_boxes_correct2
  1176   thm mv_boxes_correct2
  1167   have "{\<lambda> nl. nl = [] @ 0\<up>(length xs) @ (rec_eval (Cn (length xs) f gs) xs # 0 \<up> (?ft - length xs) @ 0 \<up> length gs) @ xs @ anything}
  1177   have "{\<lambda> nl. nl = [] @ 0\<up>(length xs) @ (rec_exec (Cn (length xs) f gs) xs # 0 \<up> (?ft - length xs) @ 0 \<up> length gs) @ xs @ anything}
  1168         mv_boxes (Suc ?ft + length gs) 0 (length xs)
  1178         mv_boxes (Suc ?ft + length gs) 0 (length xs)
  1169         {\<lambda> nl. nl = [] @ xs @ (rec_eval (Cn (length xs) f gs) xs # 0 \<up> (?ft - length xs) @ 0 \<up> length gs) @ 0\<up>length xs @ anything}"
  1179         {\<lambda> nl. nl = [] @ xs @ (rec_exec (Cn (length xs) f gs) xs # 0 \<up> (?ft - length xs) @ 0 \<up> length gs) @ 0\<up>length xs @ anything}"
  1170     by(rule_tac mv_boxes_correct2, auto)
  1180     by(rule_tac mv_boxes_correct2, auto)
  1171   thus "?thesis"
  1181   thus "?thesis"
  1172     by(simp add: replicate_merge_anywhere)
  1182     by(simp add: replicate_merge_anywhere)
  1173 qed
  1183 qed
  1174 
  1184 
  1175 lemma compile_cn_correct':
  1185 lemma compile_cn_correct':
  1176   assumes f_ind: 
  1186   assumes f_ind: 
  1177   "\<And> anything r. rec_eval f (map (\<lambda>g. rec_eval g xs) gs) = rec_eval (Cn (length xs) f gs) xs \<Longrightarrow>
  1187   "\<And> anything r. rec_exec f (map (\<lambda>g. rec_exec g xs) gs) = rec_exec (Cn (length xs) f gs) xs \<Longrightarrow>
  1178   {\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ 0 \<up> (ffp - far) @ anything} fap
  1188   {\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ 0 \<up> (ffp - far) @ anything} fap
  1179                 {\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ rec_eval (Cn (length xs) f gs) xs # 0 \<up> (ffp - Suc far) @ anything}"
  1189                 {\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ rec_exec (Cn (length xs) f gs) xs # 0 \<up> (ffp - Suc far) @ anything}"
  1180   and compile: "rec_ci f = (fap, far, ffp)"
  1190   and compile: "rec_ci f = (fap, far, ffp)"
  1181   and term_f: "terminates f (map (\<lambda>g. rec_eval g xs) gs)"
  1191   and term_f: "terminate f (map (\<lambda>g. rec_exec g xs) gs)"
  1182   and g_cond: "\<forall>g\<in>set gs. terminates g xs \<and>
  1192   and g_cond: "\<forall>g\<in>set gs. terminate g xs \<and>
  1183   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> 
  1193   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow> 
  1184   (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_eval g xs # 0 \<up> (xb - Suc xa) @ xc}))"
  1194   (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_exec g xs # 0 \<up> (xb - Suc xa) @ xc}))"
  1185   shows 
  1195   shows 
  1186   "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs) @ anything}
  1196   "{\<lambda>nl. nl = xs @ 0 # 0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs) @ anything}
  1187   cn_merge_gs (map rec_ci gs) (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) [+]
  1197   cn_merge_gs (map rec_ci gs) (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) [+]
  1188   (mv_boxes 0 (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) (length xs) [+]
  1198   (mv_boxes 0 (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) (length xs) [+]
  1189   (mv_boxes (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) 0 (length gs) [+]
  1199   (mv_boxes (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) 0 (length gs) [+]
  1190   (fap [+] (mv_box far (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) [+]
  1200   (fap [+] (mv_box far (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) [+]
  1191   (empty_boxes (length gs) [+]
  1201   (empty_boxes (length gs) [+]
  1192   (mv_box (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) (length xs) [+]
  1202   (mv_box (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))) (length xs) [+]
  1193   mv_boxes (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) 0 (length xs)))))))
  1203   mv_boxes (Suc (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs)) 0 (length xs)))))))
  1194   {\<lambda>nl. nl = xs @ rec_eval (Cn (length xs) f gs) xs # 
  1204   {\<lambda>nl. nl = xs @ rec_exec (Cn (length xs) f gs) xs # 
  1195 0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs) @ anything}"
  1205 0 \<up> (max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs))) + length gs) @ anything}"
  1196 proof -
  1206 proof -
  1197   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1207   let ?ft = "max (Suc (length xs)) (Max (insert ffp ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  1198   let ?A = "cn_merge_gs (map rec_ci gs) ?ft"
  1208   let ?A = "cn_merge_gs (map rec_ci gs) ?ft"
  1199   let ?B = "mv_boxes 0 (Suc (?ft+length gs)) (length xs)"
  1209   let ?B = "mv_boxes 0 (Suc (?ft+length gs)) (length xs)"
  1202   let ?E = "mv_box far ?ft"
  1212   let ?E = "mv_box far ?ft"
  1203   let ?F = "empty_boxes (length gs)"
  1213   let ?F = "empty_boxes (length gs)"
  1204   let ?G = "mv_box ?ft (length xs)"
  1214   let ?G = "mv_box ?ft (length xs)"
  1205   let ?H = "mv_boxes (Suc (?ft + length gs)) 0 (length xs)"
  1215   let ?H = "mv_boxes (Suc (?ft + length gs)) 0 (length xs)"
  1206   let ?P1 = "\<lambda>nl. nl = xs @ 0 # 0 \<up> (?ft + length gs) @ anything"
  1216   let ?P1 = "\<lambda>nl. nl = xs @ 0 # 0 \<up> (?ft + length gs) @ anything"
  1207   let ?S = "\<lambda>nl. nl = xs @ rec_eval (Cn (length xs) f gs) xs # 0 \<up> (?ft + length gs) @ anything"
  1217   let ?S = "\<lambda>nl. nl = xs @ rec_exec (Cn (length xs) f gs) xs # 0 \<up> (?ft + length gs) @ anything"
  1208   let ?Q1 = "\<lambda> nl. nl = xs @ 0\<up>(?ft - length xs) @ map (\<lambda> i. rec_eval i xs) gs @ 0\<up>(Suc (length xs)) @ anything"
  1218   let ?Q1 = "\<lambda> nl. nl = xs @ 0\<up>(?ft - length xs) @ map (\<lambda> i. rec_exec i xs) gs @ 0\<up>(Suc (length xs)) @ anything"
  1209   show "{?P1} (?A [+] (?B [+] (?C [+] (?D [+] (?E [+] (?F [+] (?G [+] ?H))))))) {?S}"
  1219   show "{?P1} (?A [+] (?B [+] (?C [+] (?D [+] (?E [+] (?F [+] (?G [+] ?H))))))) {?S}"
  1210   proof(rule_tac abc_Hoare_plus_halt)
  1220   proof(rule_tac abc_Hoare_plus_halt)
  1211     show "{?P1} ?A {?Q1}"
  1221     show "{?P1} ?A {?Q1}"
  1212       using g_cond
  1222       using g_cond
  1213       by(rule_tac compile_cn_gs_correct, auto)
  1223       by(rule_tac compile_cn_gs_correct, auto)
  1214   next
  1224   next
  1215     let ?Q2 = "\<lambda>nl. nl = 0 \<up> ?ft @
  1225     let ?Q2 = "\<lambda>nl. nl = 0 \<up> ?ft @
  1216                     map (\<lambda>i. rec_eval i xs) gs @ 0 # xs @ anything"
  1226                     map (\<lambda>i. rec_exec i xs) gs @ 0 # xs @ anything"
  1217     show "{?Q1} (?B [+] (?C [+] (?D [+] (?E [+] (?F [+] (?G [+] ?H)))))) {?S}"
  1227     show "{?Q1} (?B [+] (?C [+] (?D [+] (?E [+] (?F [+] (?G [+] ?H)))))) {?S}"
  1218     proof(rule_tac abc_Hoare_plus_halt)
  1228     proof(rule_tac abc_Hoare_plus_halt)
  1219       show "{?Q1} ?B {?Q2}"
  1229       show "{?Q1} ?B {?Q2}"
  1220         by(rule_tac save_paras)
  1230         by(rule_tac save_paras)
  1221     next
  1231     next
  1222       let ?Q3 = "\<lambda> nl. nl = map (\<lambda>i. rec_eval i xs) gs @ 0\<up>?ft @ 0 # xs @ anything" 
  1232       let ?Q3 = "\<lambda> nl. nl = map (\<lambda>i. rec_exec i xs) gs @ 0\<up>?ft @ 0 # xs @ anything" 
  1223       show "{?Q2} (?C [+] (?D [+] (?E [+] (?F [+] (?G [+] ?H))))) {?S}"
  1233       show "{?Q2} (?C [+] (?D [+] (?E [+] (?F [+] (?G [+] ?H))))) {?S}"
  1224       proof(rule_tac abc_Hoare_plus_halt)
  1234       proof(rule_tac abc_Hoare_plus_halt)
  1225         have "ffp \<ge> length gs"
  1235         have "ffp \<ge> length gs"
  1226           using compile term_f
  1236           using compile term_f
  1227           apply(subgoal_tac "length gs = far")
  1237           apply(subgoal_tac "length gs = far")
  1228           apply(drule_tac footprint_ge, simp)
  1238           apply(drule_tac footprint_ge, simp)
  1229           by(drule_tac param_pattern, auto)          
  1239           by(drule_tac param_pattern, auto)          
  1230         thus "{?Q2} ?C {?Q3}"
  1240         thus "{?Q2} ?C {?Q3}"
  1231           by(erule_tac restore_new_paras)
  1241           by(erule_tac restore_new_paras)
  1232       next
  1242       next
  1233         let ?Q4 = "\<lambda> nl. nl = map (\<lambda>i. rec_eval i xs) gs @ rec_eval (Cn (length xs) f gs) xs # 0\<up>?ft @ xs @ anything"
  1243         let ?Q4 = "\<lambda> nl. nl = map (\<lambda>i. rec_exec i xs) gs @ rec_exec (Cn (length xs) f gs) xs # 0\<up>?ft @ xs @ anything"
  1234         have a: "far = length gs"
  1244         have a: "far = length gs"
  1235           using compile term_f
  1245           using compile term_f
  1236           by(drule_tac param_pattern, auto)
  1246           by(drule_tac param_pattern, auto)
  1237         have b:"?ft \<ge> ffp"
  1247         have b:"?ft \<ge> ffp"
  1238           by auto
  1248           by auto
  1239         have c: "ffp > far"
  1249         have c: "ffp > far"
  1240           using compile
  1250           using compile
  1241           by(erule_tac footprint_ge)
  1251           by(erule_tac footprint_ge)
  1242         show "{?Q3} (?D [+] (?E [+] (?F [+] (?G [+] ?H)))) {?S}"
  1252         show "{?Q3} (?D [+] (?E [+] (?F [+] (?G [+] ?H)))) {?S}"
  1243         proof(rule_tac abc_Hoare_plus_halt)
  1253         proof(rule_tac abc_Hoare_plus_halt)
  1244           have "{\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ 0 \<up> (ffp - far) @ 0\<up>(?ft - ffp + far) @ 0 # xs @ anything} fap
  1254           have "{\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ 0 \<up> (ffp - far) @ 0\<up>(?ft - ffp + far) @ 0 # xs @ anything} fap
  1245             {\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ rec_eval (Cn (length xs) f gs) xs # 
  1255             {\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ rec_exec (Cn (length xs) f gs) xs # 
  1246             0 \<up> (ffp - Suc far) @ 0\<up>(?ft - ffp + far) @ 0 # xs @ anything}"
  1256             0 \<up> (ffp - Suc far) @ 0\<up>(?ft - ffp + far) @ 0 # xs @ anything}"
  1247             by(rule_tac f_ind, simp add: rec_eval.simps)
  1257             by(rule_tac f_ind, simp add: rec_exec.simps)
  1248           thus "{?Q3} fap {?Q4}"
  1258           thus "{?Q3} fap {?Q4}"
  1249             using a b c
  1259             using a b c
  1250             by(simp add: replicate_merge_anywhere,
  1260             by(simp add: replicate_merge_anywhere,
  1251                case_tac "?ft", simp_all add: exp_suc del: replicate_Suc)
  1261                case_tac "?ft", simp_all add: exp_suc del: replicate_Suc)
  1252         next
  1262         next
  1253           let ?Q5 = "\<lambda>nl. nl = map (\<lambda>i. rec_eval i xs) gs @
  1263           let ?Q5 = "\<lambda>nl. nl = map (\<lambda>i. rec_exec i xs) gs @
  1254                0\<up>(?ft - length gs) @ rec_eval (Cn (length xs) f gs) xs # 0\<up>(length gs)@ xs @ anything"
  1264                0\<up>(?ft - length gs) @ rec_exec (Cn (length xs) f gs) xs # 0\<up>(length gs)@ xs @ anything"
  1255           show "{?Q4} (?E [+] (?F [+] (?G [+] ?H))) {?S}"
  1265           show "{?Q4} (?E [+] (?F [+] (?G [+] ?H))) {?S}"
  1256           proof(rule_tac abc_Hoare_plus_halt)
  1266           proof(rule_tac abc_Hoare_plus_halt)
  1257             from a b c show "{?Q4} ?E {?Q5}"
  1267             from a b c show "{?Q4} ?E {?Q5}"
  1258               by(erule_tac save_rs, simp_all)
  1268               by(erule_tac save_rs, simp_all)
  1259           next
  1269           next
  1260             let ?Q6 = "\<lambda>nl. nl = 0\<up>?ft @ rec_eval (Cn (length xs) f gs) xs # 0\<up>(length gs)@ xs @ anything"
  1270             let ?Q6 = "\<lambda>nl. nl = 0\<up>?ft @ rec_exec (Cn (length xs) f gs) xs # 0\<up>(length gs)@ xs @ anything"
  1261             show "{?Q5} (?F [+] (?G [+] ?H)) {?S}"
  1271             show "{?Q5} (?F [+] (?G [+] ?H)) {?S}"
  1262             proof(rule_tac abc_Hoare_plus_halt)
  1272             proof(rule_tac abc_Hoare_plus_halt)
  1263               have "length gs \<le> ffp" using a b c
  1273               have "length gs \<le> ffp" using a b c
  1264                 by simp
  1274                 by simp
  1265               thus "{?Q5} ?F {?Q6}"
  1275               thus "{?Q5} ?F {?Q6}"
  1266                 by(erule_tac clean_paras)
  1276                 by(erule_tac clean_paras)
  1267             next
  1277             next
  1268               let ?Q7 = "\<lambda>nl. nl = 0\<up>length xs @ rec_eval (Cn (length xs) f gs) xs # 0\<up>(?ft - (length xs)) @ 0\<up>(length gs)@ xs @ anything"
  1278               let ?Q7 = "\<lambda>nl. nl = 0\<up>length xs @ rec_exec (Cn (length xs) f gs) xs # 0\<up>(?ft - (length xs)) @ 0\<up>(length gs)@ xs @ anything"
  1269               show "{?Q6} (?G [+] ?H) {?S}"
  1279               show "{?Q6} (?G [+] ?H) {?S}"
  1270               proof(rule_tac abc_Hoare_plus_halt)
  1280               proof(rule_tac abc_Hoare_plus_halt)
  1271                 show "{?Q6} ?G {?Q7}"
  1281                 show "{?Q6} ?G {?Q7}"
  1272                   by(rule_tac restore_rs)
  1282                   by(rule_tac restore_rs)
  1273               next
  1283               next
  1281     qed
  1291     qed
  1282   qed
  1292   qed
  1283 qed
  1293 qed
  1284 
  1294 
  1285 lemma compile_cn_correct:
  1295 lemma compile_cn_correct:
  1286   assumes termi_f: "terminates f (map (\<lambda>g. rec_eval g xs) gs)"
  1296   assumes termi_f: "terminate f (map (\<lambda>g. rec_exec g xs) gs)"
  1287   and f_ind: "\<And>ap arity fp anything.
  1297   and f_ind: "\<And>ap arity fp anything.
  1288   rec_ci f = (ap, arity, fp)
  1298   rec_ci f = (ap, arity, fp)
  1289   \<Longrightarrow> {\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ 0 \<up> (fp - arity) @ anything} ap
  1299   \<Longrightarrow> {\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ 0 \<up> (fp - arity) @ anything} ap
  1290   {\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ rec_eval f (map (\<lambda>g. rec_eval g xs) gs) # 0 \<up> (fp - Suc arity) @ anything}"
  1300   {\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ rec_exec f (map (\<lambda>g. rec_exec g xs) gs) # 0 \<up> (fp - Suc arity) @ anything}"
  1291   and g_cond: 
  1301   and g_cond: 
  1292   "\<forall>g\<in>set gs. terminates g xs \<and>
  1302   "\<forall>g\<in>set gs. terminate g xs \<and>
  1293   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow>   (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_eval g xs # 0 \<up> (xb - Suc xa) @ xc}))"
  1303   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow>   (\<forall>xc. {\<lambda>nl. nl = xs @ 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ rec_exec g xs # 0 \<up> (xb - Suc xa) @ xc}))"
  1294   and compile: "rec_ci (Cn n f gs) = (ap, arity, fp)"
  1304   and compile: "rec_ci (Cn n f gs) = (ap, arity, fp)"
  1295   and len: "length xs = n"
  1305   and len: "length xs = n"
  1296   shows "{\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ rec_eval (Cn n f gs) xs # 0 \<up> (fp - Suc arity) @ anything}"
  1306   shows "{\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ rec_exec (Cn n f gs) xs # 0 \<up> (fp - Suc arity) @ anything}"
  1297 proof(case_tac "rec_ci f")
  1307 proof(case_tac "rec_ci f")
  1298   fix fap far ffp
  1308   fix fap far ffp
  1299   assume h: "rec_ci f = (fap, far, ffp)"
  1309   assume h: "rec_ci f = (fap, far, ffp)"
  1300   then have f_newind: "\<And> anything .{\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ 0 \<up> (ffp - far) @ anything} fap
  1310   then have f_newind: "\<And> anything .{\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ 0 \<up> (ffp - far) @ anything} fap
  1301     {\<lambda>nl. nl = map (\<lambda>g. rec_eval g xs) gs @ rec_eval f (map (\<lambda>g. rec_eval g xs) gs) # 0 \<up> (ffp - Suc far) @ anything}"
  1311     {\<lambda>nl. nl = map (\<lambda>g. rec_exec g xs) gs @ rec_exec f (map (\<lambda>g. rec_exec g xs) gs) # 0 \<up> (ffp - Suc far) @ anything}"
  1302     by(rule_tac f_ind, simp_all)
  1312     by(rule_tac f_ind, simp_all)
  1303   thus "{\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ rec_eval (Cn n f gs) xs # 0 \<up> (fp - Suc arity) @ anything}"
  1313   thus "{\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ rec_exec (Cn n f gs) xs # 0 \<up> (fp - Suc arity) @ anything}"
  1304     using compile len h termi_f g_cond
  1314     using compile len h termi_f g_cond
  1305     apply(auto simp: rec_ci.simps abc_comp_commute)
  1315     apply(auto simp: rec_ci.simps abc_comp_commute)
  1306     apply(rule_tac compile_cn_correct', simp_all)
  1316     apply(rule_tac compile_cn_correct', simp_all)
  1307     done
  1317     done
  1308 qed
  1318 qed
  1317 lemma [simp]: "length xs < max (length xs + 3) (max fft gft)"
  1327 lemma [simp]: "length xs < max (length xs + 3) (max fft gft)"
  1318 by auto
  1328 by auto
  1319 
  1329 
  1320 lemma save_init_rs: 
  1330 lemma save_init_rs: 
  1321   "\<lbrakk>length xs = n; ft = max (n+3) (max fft gft)\<rbrakk> 
  1331   "\<lbrakk>length xs = n; ft = max (n+3) (max fft gft)\<rbrakk> 
  1322      \<Longrightarrow>  {\<lambda>nl. nl = xs @ rec_eval f xs # 0 \<up> (ft - n) @ anything} mv_box n (Suc n) 
  1332      \<Longrightarrow>  {\<lambda>nl. nl = xs @ rec_exec f xs # 0 \<up> (ft - n) @ anything} mv_box n (Suc n) 
  1323        {\<lambda>nl. nl = xs @ 0 # rec_eval f xs # 0 \<up> (ft - Suc n) @ anything}"
  1333        {\<lambda>nl. nl = xs @ 0 # rec_exec f xs # 0 \<up> (ft - Suc n) @ anything}"
  1324 using mv_box_correct[of n "Suc n" "xs @ rec_eval f xs # 0 \<up> (ft - n) @ anything"]
  1334 using mv_box_correct[of n "Suc n" "xs @ rec_exec f xs # 0 \<up> (ft - n) @ anything"]
  1325 apply(auto simp: list_update_append list_update.simps nth_append split: if_splits)
  1335 apply(auto simp: list_update_append list_update.simps nth_append split: if_splits)
  1326 apply(case_tac "(max (length xs + 3) (max fft gft))", simp_all add: list_update.simps Suc_diff_le)
  1336 apply(case_tac "(max (length xs + 3) (max fft gft))", simp_all add: list_update.simps Suc_diff_le)
  1327 done
  1337 done
  1328 
  1338 
  1329 lemma [simp]: "n + (2::nat) < max (n + 3) (max fft gft)"
  1339 lemma [simp]: "n + (2::nat) < max (n + 3) (max fft gft)"
  1369 lemma [simp]: "Suc n < max (n + 3) (max fft gft)"
  1379 lemma [simp]: "Suc n < max (n + 3) (max fft gft)"
  1370 by arith
  1380 by arith
  1371 
  1381 
  1372 lemma [simp]:
  1382 lemma [simp]:
  1373   "length xs = n
  1383   "length xs = n
  1374  \<Longrightarrow> {\<lambda>nl. nl = xs @ rec_eval f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ x # anything} mv_box n (Suc n)
  1384  \<Longrightarrow> {\<lambda>nl. nl = xs @ rec_exec f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ x # anything} mv_box n (Suc n)
  1375     {\<lambda>nl. nl = xs @ 0 # rec_eval f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc (Suc n)) @ x # anything}"
  1385     {\<lambda>nl. nl = xs @ 0 # rec_exec f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc (Suc n)) @ x # anything}"
  1376 using mv_box_correct[of n "Suc n" "xs @ rec_eval f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ x # anything"]
  1386 using mv_box_correct[of n "Suc n" "xs @ rec_exec f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ x # anything"]
  1377 apply(simp add: nth_append list_update_append list_update.simps)
  1387 apply(simp add: nth_append list_update_append list_update.simps)
  1378 apply(case_tac "max (n + 3) (max fft gft)", simp_all)
  1388 apply(case_tac "max (n + 3) (max fft gft)", simp_all)
  1379 apply(case_tac nat, simp_all add: Suc_diff_le list_update.simps)
  1389 apply(case_tac nat, simp_all add: Suc_diff_le list_update.simps)
  1380 done
  1390 done
  1381 
  1391 
  1455 lemma [simp]: "Suc (Suc (max (length xs + 3) (max fft gft) - Suc (Suc (length xs))))
  1465 lemma [simp]: "Suc (Suc (max (length xs + 3) (max fft gft) - Suc (Suc (length xs))))
  1456            = max (length xs + 3) (max fft gft) - (length xs)"
  1466            = max (length xs + 3) (max fft gft) - (length xs)"
  1457 by arith
  1467 by arith
  1458 
  1468 
  1459 lemma [simp]: "\<lbrakk>ft = max (n + 3) (max fft gft); length xs = n\<rbrakk> \<Longrightarrow>
  1469 lemma [simp]: "\<lbrakk>ft = max (n + 3) (max fft gft); length xs = n\<rbrakk> \<Longrightarrow>
  1460      {\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything}
  1470      {\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything}
  1461      [Dec ft (length gap + 7)] 
  1471      [Dec ft (length gap + 7)] 
  1462      {\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything}"
  1472      {\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything}"
  1463 apply(simp add: abc_Hoare_halt_def)
  1473 apply(simp add: abc_Hoare_halt_def)
  1464 apply(rule_tac x = 1 in exI)
  1474 apply(rule_tac x = 1 in exI)
  1465 apply(auto simp: abc_steps_l.simps abc_step_l.simps abc_fetch.simps nth_append abc_lm_v.simps abc_lm_s.simps list_update_append)
  1475 apply(auto simp: abc_steps_l.simps abc_step_l.simps abc_fetch.simps nth_append abc_lm_v.simps abc_lm_s.simps list_update_append)
  1466 using list_update_length
  1476 using list_update_length
  1467 [of "(x - Suc y) # rec_eval (Pr (length xs) f g) (xs @ [x - Suc y]) #
  1477 [of "(x - Suc y) # rec_exec (Pr (length xs) f g) (xs @ [x - Suc y]) #
  1468           0 \<up> (max (length xs + 3) (max fft gft) - Suc (Suc (length xs)))" "Suc y" anything y]
  1478           0 \<up> (max (length xs + 3) (max fft gft) - Suc (Suc (length xs)))" "Suc y" anything y]
  1469 apply(simp)
  1479 apply(simp)
  1470 done
  1480 done
  1471 
  1481 
  1472 lemma adjust_paras': 
  1482 lemma adjust_paras': 
  1514   "length xs = n \<Longrightarrow> {\<lambda>nl. nl = xs @ x # y # anything}  [Inc n, Dec (Suc n) 3, Goto (Suc 0)]
  1524   "length xs = n \<Longrightarrow> {\<lambda>nl. nl = xs @ x # y # anything}  [Inc n, Dec (Suc n) 3, Goto (Suc 0)]
  1515        {\<lambda>nl. nl = xs @ Suc x # 0 # anything}"
  1525        {\<lambda>nl. nl = xs @ Suc x # 0 # anything}"
  1516 using adjust_paras'[of xs n x y anything]
  1526 using adjust_paras'[of xs n x y anything]
  1517 by(simp add: abc_comp.simps abc_shift.simps numeral_2_eq_2 numeral_3_eq_3)
  1527 by(simp add: abc_comp.simps abc_shift.simps numeral_2_eq_2 numeral_3_eq_3)
  1518 
  1528 
  1519 lemma [simp]: "\<lbrakk>rec_ci g = (gap, gar, gft); \<forall>y<x. terminates g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]);
  1529 lemma [simp]: "\<lbrakk>rec_ci g = (gap, gar, gft); \<forall>y<x. terminate g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]);
  1520         length xs = n; Suc y\<le>x\<rbrakk> \<Longrightarrow> gar = Suc (Suc n)"
  1530         length xs = n; Suc y\<le>x\<rbrakk> \<Longrightarrow> gar = Suc (Suc n)"
  1521   apply(erule_tac x = y in allE, simp)
  1531   apply(erule_tac x = y in allE, simp)
  1522   apply(drule_tac param_pattern, auto)
  1532   apply(drule_tac param_pattern, auto)
  1523   done
  1533   done
  1524 
  1534 
  1561 apply(rule_tac x = "stp + 1" in exI)
  1571 apply(rule_tac x = "stp + 1" in exI)
  1562 apply(simp only: abc_steps_add, simp)
  1572 apply(simp only: abc_steps_add, simp)
  1563 apply(simp add: abc_steps_l.simps abc_step_l.simps abc_fetch.simps nth_append abc_lm_v.simps abc_lm_s.simps)
  1573 apply(simp add: abc_steps_l.simps abc_step_l.simps abc_fetch.simps nth_append abc_lm_v.simps abc_lm_s.simps)
  1564 done
  1574 done
  1565 
  1575 
  1566 lemma rec_eval_pr_0_simps: "rec_eval (Pr n f g) (xs @ [0]) = rec_eval f xs"
  1576 lemma rec_exec_pr_0_simps: "rec_exec (Pr n f g) (xs @ [0]) = rec_exec f xs"
  1567  by(simp add: rec_eval.simps)
  1577  by(simp add: rec_exec.simps)
  1568 
  1578 
  1569 lemma rec_eval_pr_Suc_simps: "rec_eval (Pr n f g) (xs @ [Suc y])
  1579 lemma rec_exec_pr_Suc_simps: "rec_exec (Pr n f g) (xs @ [Suc y])
  1570           = rec_eval g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])])"
  1580           = rec_exec g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])])"
  1571 apply(induct y)
  1581 apply(induct y)
  1572 apply(simp add: rec_eval.simps)
  1582 apply(simp add: rec_exec.simps)
  1573 apply(simp add: rec_eval.simps)
  1583 apply(simp add: rec_exec.simps)
  1574 done
  1584 done
  1575 
  1585 
  1576 lemma [simp]: "Suc (max (n + 3) (max fft gft) - Suc (Suc (Suc n))) = max (n + 3) (max fft gft) - Suc (Suc n)"
  1586 lemma [simp]: "Suc (max (n + 3) (max fft gft) - Suc (Suc (Suc n))) = max (n + 3) (max fft gft) - Suc (Suc n)"
  1577 by arith
  1587 by arith
  1578 
  1588 
  1579 lemma pr_loop:
  1589 lemma pr_loop:
  1580   assumes code: "code = ([Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)])) @
  1590   assumes code: "code = ([Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)])) @
  1581     [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1591     [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1582   and len: "length xs = n"
  1592   and len: "length xs = n"
  1583   and g_ind: "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1593   and g_ind: "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1584   {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # rec_eval g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1594   {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # rec_exec g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1585   and compile_g: "rec_ci g = (gap, gar, gft)"
  1595   and compile_g: "rec_ci g = (gap, gar, gft)"
  1586   and termi_g: "\<forall> y<x. terminates g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])])"
  1596   and termi_g: "\<forall> y<x. terminate g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])])"
  1587   and ft: "ft = max (n + 3) (max fft gft)"
  1597   and ft: "ft = max (n + 3) (max fft gft)"
  1588   and less: "Suc y \<le> x"
  1598   and less: "Suc y \<le> x"
  1589   shows 
  1599   shows 
  1590   "\<exists>stp. abc_steps_l (0, xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1600   "\<exists>stp. abc_steps_l (0, xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1591   code stp = (0, xs @ (x - y) # rec_eval (Pr n f g) (xs @ [x - y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything)"
  1601   code stp = (0, xs @ (x - y) # rec_exec (Pr n f g) (xs @ [x - y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything)"
  1592 proof -
  1602 proof -
  1593   let ?A = "[Dec  ft (length gap + 7)]"
  1603   let ?A = "[Dec  ft (length gap + 7)]"
  1594   let ?B = "gap"
  1604   let ?B = "gap"
  1595   let ?C = "[Inc n, Dec (Suc n) 3, Goto (Suc 0)]"
  1605   let ?C = "[Inc n, Dec (Suc n) 3, Goto (Suc 0)]"
  1596   let ?D = "[Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1606   let ?D = "[Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1597   have "\<exists> stp. abc_steps_l (0, xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1607   have "\<exists> stp. abc_steps_l (0, xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1598             ((?A [+] (?B [+] ?C)) @ ?D) stp = (length (?A [+] (?B [+] ?C)), 
  1608             ((?A [+] (?B [+] ?C)) @ ?D) stp = (length (?A [+] (?B [+] ?C)), 
  1599           xs @ (x - y) # 0 # rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])])
  1609           xs @ (x - y) # 0 # rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])])
  1600                   # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)"
  1610                   # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)"
  1601   proof -
  1611   proof -
  1602     have "\<exists> stp. abc_steps_l (0, xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1612     have "\<exists> stp. abc_steps_l (0, xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1603       ((?A [+] (?B [+] ?C))) stp = (length (?A [+] (?B [+] ?C)),  xs @ (x - y) # 0 # 
  1613       ((?A [+] (?B [+] ?C))) stp = (length (?A [+] (?B [+] ?C)),  xs @ (x - y) # 0 # 
  1604       rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)"
  1614       rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)"
  1605     proof -
  1615     proof -
  1606       have "{\<lambda> nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything}
  1616       have "{\<lambda> nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything}
  1607         (?A [+] (?B [+] ?C)) 
  1617         (?A [+] (?B [+] ?C)) 
  1608         {\<lambda> nl. nl = xs @ (x - y) # 0 # 
  1618         {\<lambda> nl. nl = xs @ (x - y) # 0 # 
  1609         rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1619         rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1610       proof(rule_tac abc_Hoare_plus_halt)
  1620       proof(rule_tac abc_Hoare_plus_halt)
  1611         show "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything}
  1621         show "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything}
  1612           [Dec ft (length gap + 7)] 
  1622           [Dec ft (length gap + 7)] 
  1613           {\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything}"
  1623           {\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything}"
  1614           using ft len
  1624           using ft len
  1615           by(simp)
  1625           by(simp)
  1616       next
  1626       next
  1617         show 
  1627         show 
  1618           "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything} 
  1628           "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything} 
  1619           ?B [+] ?C
  1629           ?B [+] ?C
  1620           {\<lambda>nl. nl = xs @ (x - y) # 0 # rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1630           {\<lambda>nl. nl = xs @ (x - y) # 0 # rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1621         proof(rule_tac abc_Hoare_plus_halt)
  1631         proof(rule_tac abc_Hoare_plus_halt)
  1622           have a: "gar = Suc (Suc n)" 
  1632           have a: "gar = Suc (Suc n)" 
  1623             using compile_g termi_g len less
  1633             using compile_g termi_g len less
  1624             by simp
  1634             by simp
  1625           have b: "gft > gar"
  1635           have b: "gft > gar"
  1626             using compile_g
  1636             using compile_g
  1627             by(erule_tac footprint_ge)
  1637             by(erule_tac footprint_ge)
  1628           show "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything} gap 
  1638           show "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ y # anything} gap 
  1629                 {\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 
  1639                 {\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 
  1630                       rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1640                       rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1631           proof -
  1641           proof -
  1632             have 
  1642             have 
  1633               "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (gft - gar) @ 0\<up>(ft - gft) @ y # anything} gap
  1643               "{\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (gft - gar) @ 0\<up>(ft - gft) @ y # anything} gap
  1634               {\<lambda>nl. nl = xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 
  1644               {\<lambda>nl. nl = xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 
  1635               rec_eval g (xs @ [(x - Suc y), rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (gft - Suc gar) @ 0\<up>(ft - gft) @ y # anything}"
  1645               rec_exec g (xs @ [(x - Suc y), rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (gft - Suc gar) @ 0\<up>(ft - gft) @ y # anything}"
  1636               using g_ind less by simp
  1646               using g_ind less by simp
  1637             thus "?thesis"
  1647             thus "?thesis"
  1638               using a b ft
  1648               using a b ft
  1639               by(simp add: replicate_merge_anywhere numeral_3_eq_3)
  1649               by(simp add: replicate_merge_anywhere numeral_3_eq_3)
  1640           qed
  1650           qed
  1641         next
  1651         next
  1642           show "{\<lambda>nl. nl = xs @ (x - Suc y) #
  1652           show "{\<lambda>nl. nl = xs @ (x - Suc y) #
  1643                     rec_eval (Pr n f g) (xs @ [x - Suc y]) #
  1653                     rec_exec (Pr n f g) (xs @ [x - Suc y]) #
  1644             rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}
  1654             rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}
  1645             [Inc n, Dec (Suc n) 3, Goto (Suc 0)]
  1655             [Inc n, Dec (Suc n) 3, Goto (Suc 0)]
  1646             {\<lambda>nl. nl = xs @ (x - y) # 0 # rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) 
  1656             {\<lambda>nl. nl = xs @ (x - y) # 0 # rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) 
  1647                     (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1657                     (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything}"
  1648             using len less
  1658             using len less
  1649             using adjust_paras[of xs n "x - Suc y" " rec_eval (Pr n f g) (xs @ [x - Suc y])"
  1659             using adjust_paras[of xs n "x - Suc y" " rec_exec (Pr n f g) (xs @ [x - Suc y])"
  1650               " rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 
  1660               " rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 
  1651               0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything"]
  1661               0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything"]
  1652             by(simp add: Suc_diff_Suc)
  1662             by(simp add: Suc_diff_Suc)
  1653         qed
  1663         qed
  1654       qed
  1664       qed
  1655       thus "?thesis"
  1665       thus "?thesis"
  1656         by(simp add: abc_Hoare_halt_def, auto, rule_tac x = na in exI, case_tac "abc_steps_l (0, xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 
  1666         by(simp add: abc_Hoare_halt_def, auto, rule_tac x = na in exI, case_tac "abc_steps_l (0, xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 
  1657           0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1667           0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1658              ([Dec ft (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)])) na", simp)
  1668              ([Dec ft (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)])) na", simp)
  1659     qed
  1669     qed
  1660     then obtain stpa where "abc_steps_l (0, xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1670     then obtain stpa where "abc_steps_l (0, xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (ft - Suc (Suc n)) @ Suc y # anything)
  1661             ((?A [+] (?B [+] ?C))) stpa = (length (?A [+] (?B [+] ?C)), 
  1671             ((?A [+] (?B [+] ?C))) stpa = (length (?A [+] (?B [+] ?C)), 
  1662           xs @ (x - y) # 0 # rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])])
  1672           xs @ (x - y) # 0 # rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])])
  1663                   # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)" ..
  1673                   # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)" ..
  1664     thus "?thesis"
  1674     thus "?thesis"
  1665       by(erule_tac abc_append_frist_steps_halt_eq)
  1675       by(erule_tac abc_append_frist_steps_halt_eq)
  1666   qed
  1676   qed
  1667   moreover have 
  1677   moreover have 
  1668     "\<exists> stp. abc_steps_l (length (?A [+] (?B [+] ?C)),
  1678     "\<exists> stp. abc_steps_l (length (?A [+] (?B [+] ?C)),
  1669     xs @ (x - y) # 0 # rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)
  1679     xs @ (x - y) # 0 # rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)
  1670     ((?A [+] (?B [+] ?C)) @ ?D) stp  = (0, xs @ (x - y) # rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) # 
  1680     ((?A [+] (?B [+] ?C)) @ ?D) stp  = (0, xs @ (x - y) # rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) # 
  1671     0 # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)"
  1681     0 # 0 \<up> (ft - Suc (Suc (Suc n))) @ y # anything)"
  1672     using len
  1682     using len
  1673     by(rule_tac loop_back, simp_all)
  1683     by(rule_tac loop_back, simp_all)
  1674   moreover have "rec_eval g (xs @ [x - Suc y, rec_eval (Pr n f g) (xs @ [x - Suc y])]) = rec_eval (Pr n f g) (xs @ [x - y])"
  1684   moreover have "rec_exec g (xs @ [x - Suc y, rec_exec (Pr n f g) (xs @ [x - Suc y])]) = rec_exec (Pr n f g) (xs @ [x - y])"
  1675     using less
  1685     using less
  1676     thm rec_eval.simps
  1686     thm rec_exec.simps
  1677     apply(case_tac "x - y", simp_all add: rec_eval_pr_Suc_simps)
  1687     apply(case_tac "x - y", simp_all add: rec_exec_pr_Suc_simps)
  1678     by(subgoal_tac "nat = x - Suc y", simp, arith)    
  1688     by(subgoal_tac "nat = x - Suc y", simp, arith)    
  1679   ultimately show "?thesis"
  1689   ultimately show "?thesis"
  1680     using code ft
  1690     using code ft
  1681     by(auto, rule_tac x = "stp + stpa" in exI, simp add: abc_steps_add replicate_Suc_iff_anywhere del: replicate_Suc)
  1691     by(auto, rule_tac x = "stp + stpa" in exI, simp add: abc_steps_add replicate_Suc_iff_anywhere del: replicate_Suc)
  1682 qed
  1692 qed
  1683 
  1693 
  1684 lemma [simp]: 
  1694 lemma [simp]: 
  1685   "length xs = n \<Longrightarrow> abc_lm_s (xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) 
  1695   "length xs = n \<Longrightarrow> abc_lm_s (xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) 
  1686   (max fft gft) - Suc (Suc n)) @ 0 # anything) (max (n + 3) (max fft gft)) 0 =
  1696   (max fft gft) - Suc (Suc n)) @ 0 # anything) (max (n + 3) (max fft gft)) 0 =
  1687     xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ anything"
  1697     xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ anything"
  1688 apply(simp add: abc_lm_s.simps)
  1698 apply(simp add: abc_lm_s.simps)
  1689 using list_update_length[of "xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc (Suc n))"
  1699 using list_update_length[of "xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc (Suc n))"
  1690                         0 anything 0]
  1700                         0 anything 0]
  1691 apply(auto simp: Suc_diff_Suc)
  1701 apply(auto simp: Suc_diff_Suc)
  1692 apply(simp add: exp_suc[THEN sym] Suc_diff_Suc  del: replicate_Suc)
  1702 apply(simp add: exp_suc[THEN sym] Suc_diff_Suc  del: replicate_Suc)
  1693 done
  1703 done
  1694 
  1704 
  1695 lemma [simp]:
  1705 lemma [simp]:
  1696   "(xs @ x # rec_eval (Pr (length xs) f g) (xs @ [x]) # 0 \<up> (max (length xs + 3)
  1706   "(xs @ x # rec_exec (Pr (length xs) f g) (xs @ [x]) # 0 \<up> (max (length xs + 3)
  1697   (max fft gft) - Suc (Suc (length xs))) @ 0 # anything) !
  1707   (max fft gft) - Suc (Suc (length xs))) @ 0 # anything) !
  1698     max (length xs + 3) (max fft gft) = 0"
  1708     max (length xs + 3) (max fft gft) = 0"
  1699 using nth_append_length[of "xs @ x # rec_eval (Pr (length xs) f g) (xs @ [x]) #
  1709 using nth_append_length[of "xs @ x # rec_exec (Pr (length xs) f g) (xs @ [x]) #
  1700   0 \<up> (max (length xs + 3) (max fft gft) - Suc (Suc (length xs)))" 0  anything]
  1710   0 \<up> (max (length xs + 3) (max fft gft) - Suc (Suc (length xs)))" 0  anything]
  1701 by(simp)
  1711 by(simp)
  1702 
  1712 
  1703 lemma pr_loop_correct:
  1713 lemma pr_loop_correct:
  1704   assumes less: "y \<le> x" 
  1714   assumes less: "y \<le> x" 
  1705   and len: "length xs = n"
  1715   and len: "length xs = n"
  1706   and compile_g: "rec_ci g = (gap, gar, gft)"
  1716   and compile_g: "rec_ci g = (gap, gar, gft)"
  1707   and termi_g: "\<forall> y<x. terminates g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])])"
  1717   and termi_g: "\<forall> y<x. terminate g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])])"
  1708   and g_ind: "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1718   and g_ind: "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1709   {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # rec_eval g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1719   {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # rec_exec g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1710   shows "{\<lambda>nl. nl = xs @ (x - y) # rec_eval (Pr n f g) (xs @ [x - y]) # 0 \<up> (max (n + 3) (max fft gft) - Suc (Suc n)) @ y # anything}
  1720   shows "{\<lambda>nl. nl = xs @ (x - y) # rec_exec (Pr n f g) (xs @ [x - y]) # 0 \<up> (max (n + 3) (max fft gft) - Suc (Suc n)) @ y # anything}
  1711    ([Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)])) @ [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]
  1721    ([Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)])) @ [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]
  1712    {\<lambda>nl. nl = xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ anything}" 
  1722    {\<lambda>nl. nl = xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ anything}" 
  1713   using less
  1723   using less
  1714 proof(induct y)
  1724 proof(induct y)
  1715   case 0
  1725   case 0
  1716   thus "?case"
  1726   thus "?case"
  1717     using len
  1727     using len
  1723   case (Suc y)
  1733   case (Suc y)
  1724   let ?ft = "max (n + 3) (max fft gft)"
  1734   let ?ft = "max (n + 3) (max fft gft)"
  1725   let ?C = "[Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] 
  1735   let ?C = "[Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] 
  1726     [Inc n, Dec (Suc n) 3, Goto (Suc 0)]) @ [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1736     [Inc n, Dec (Suc n) 3, Goto (Suc 0)]) @ [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1727   have ind: "y \<le> x \<Longrightarrow>
  1737   have ind: "y \<le> x \<Longrightarrow>
  1728          {\<lambda>nl. nl = xs @ (x - y) # rec_eval (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything}
  1738          {\<lambda>nl. nl = xs @ (x - y) # rec_exec (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything}
  1729          ?C {\<lambda>nl. nl = xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything}" by fact 
  1739          ?C {\<lambda>nl. nl = xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything}" by fact 
  1730   have less: "Suc y \<le> x" by fact
  1740   have less: "Suc y \<le> x" by fact
  1731   have stp1: 
  1741   have stp1: 
  1732     "\<exists> stp. abc_steps_l (0, xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (?ft - Suc (Suc n)) @ Suc y # anything)
  1742     "\<exists> stp. abc_steps_l (0, xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (?ft - Suc (Suc n)) @ Suc y # anything)
  1733     ?C stp  = (0, xs @ (x - y) # rec_eval (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)"
  1743     ?C stp  = (0, xs @ (x - y) # rec_exec (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)"
  1734     using assms less
  1744     using assms less
  1735     by(rule_tac  pr_loop, auto)
  1745     by(rule_tac  pr_loop, auto)
  1736   then obtain stp1 where a:
  1746   then obtain stp1 where a:
  1737     "abc_steps_l (0, xs @ (x - Suc y) # rec_eval (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (?ft - Suc (Suc n)) @ Suc y # anything)
  1747     "abc_steps_l (0, xs @ (x - Suc y) # rec_exec (Pr n f g) (xs @ [x - Suc y]) # 0 \<up> (?ft - Suc (Suc n)) @ Suc y # anything)
  1738    ?C stp1 = (0, xs @ (x - y) # rec_eval (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)" ..
  1748    ?C stp1 = (0, xs @ (x - y) # rec_exec (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)" ..
  1739   moreover have 
  1749   moreover have 
  1740     "\<exists> stp. abc_steps_l (0, xs @ (x - y) # rec_eval (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)
  1750     "\<exists> stp. abc_steps_l (0, xs @ (x - y) # rec_exec (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)
  1741     ?C stp = (length ?C, xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything)"
  1751     ?C stp = (length ?C, xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything)"
  1742     using ind less
  1752     using ind less
  1743     by(auto simp: abc_Hoare_halt_def, case_tac "abc_steps_l (0, xs @ (x - y) # rec_eval (Pr n f g) 
  1753     by(auto simp: abc_Hoare_halt_def, case_tac "abc_steps_l (0, xs @ (x - y) # rec_exec (Pr n f g) 
  1744       (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything) ?C na", rule_tac x = na in exI, simp)
  1754       (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything) ?C na", rule_tac x = na in exI, simp)
  1745   then obtain stp2 where b:
  1755   then obtain stp2 where b:
  1746     "abc_steps_l (0, xs @ (x - y) # rec_eval (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)
  1756     "abc_steps_l (0, xs @ (x - y) # rec_exec (Pr n f g) (xs @ [x - y]) # 0 \<up> (?ft - Suc (Suc n)) @ y # anything)
  1747     ?C stp2 = (length ?C, xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything)" ..
  1757     ?C stp2 = (length ?C, xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything)" ..
  1748   from a b show "?case"
  1758   from a b show "?case"
  1749     by(simp add: abc_Hoare_halt_def, rule_tac x = "stp1 + stp2" in exI, simp add: abc_steps_add)
  1759     by(simp add: abc_Hoare_halt_def, rule_tac x = "stp1 + stp2" in exI, simp add: abc_steps_add)
  1750 qed
  1760 qed
  1751 
  1761 
  1752 lemma compile_pr_correct':
  1762 lemma compile_pr_correct':
  1753   assumes termi_g: "\<forall> y<x. terminates g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])])"
  1763   assumes termi_g: "\<forall> y<x. terminate g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])])"
  1754   and g_ind: 
  1764   and g_ind: 
  1755   "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1765   "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1756   {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # rec_eval g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1766   {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # rec_exec g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1757   and termi_f: "terminates f xs"
  1767   and termi_f: "terminate f xs"
  1758   and f_ind: "\<And> anything. {\<lambda>nl. nl = xs @ 0 \<up> (fft - far) @ anything} fap {\<lambda>nl. nl = xs @ rec_eval f xs # 0 \<up> (fft - Suc far) @ anything}"
  1768   and f_ind: "\<And> anything. {\<lambda>nl. nl = xs @ 0 \<up> (fft - far) @ anything} fap {\<lambda>nl. nl = xs @ rec_exec f xs # 0 \<up> (fft - Suc far) @ anything}"
  1759   and len: "length xs = n"
  1769   and len: "length xs = n"
  1760   and compile1: "rec_ci f = (fap, far, fft)"
  1770   and compile1: "rec_ci f = (fap, far, fft)"
  1761   and compile2: "rec_ci g = (gap, gar, gft)"
  1771   and compile2: "rec_ci g = (gap, gar, gft)"
  1762   shows 
  1772   shows 
  1763   "{\<lambda>nl. nl = xs @ x # 0 \<up> (max (n + 3) (max fft gft) - n) @ anything}
  1773   "{\<lambda>nl. nl = xs @ x # 0 \<up> (max (n + 3) (max fft gft) - n) @ anything}
  1764   mv_box n (max (n + 3) (max fft gft)) [+]
  1774   mv_box n (max (n + 3) (max fft gft)) [+]
  1765   (fap [+] (mv_box n (Suc n) [+]
  1775   (fap [+] (mv_box n (Suc n) [+]
  1766   ([Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)]) @
  1776   ([Dec (max (n + 3) (max fft gft)) (length gap + 7)] [+] (gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)]) @
  1767   [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)])))
  1777   [Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)])))
  1768   {\<lambda>nl. nl = xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ anything}"
  1778   {\<lambda>nl. nl = xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ anything}"
  1769 proof -
  1779 proof -
  1770   let ?ft = "max (n+3) (max fft gft)"
  1780   let ?ft = "max (n+3) (max fft gft)"
  1771   let ?A = "mv_box n ?ft"
  1781   let ?A = "mv_box n ?ft"
  1772   let ?B = "fap"
  1782   let ?B = "fap"
  1773   let ?C = "mv_box n (Suc n)"
  1783   let ?C = "mv_box n (Suc n)"
  1774   let ?D = "[Dec ?ft (length gap + 7)]"
  1784   let ?D = "[Dec ?ft (length gap + 7)]"
  1775   let ?E = "gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)]"
  1785   let ?E = "gap [+] [Inc n, Dec (Suc n) 3, Goto (Suc 0)]"
  1776   let ?F = "[Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1786   let ?F = "[Dec (Suc (Suc n)) 0, Inc (Suc n), Goto (length gap + 4)]"
  1777   let ?P = "\<lambda>nl. nl = xs @ x # 0 \<up> (?ft - n) @ anything"
  1787   let ?P = "\<lambda>nl. nl = xs @ x # 0 \<up> (?ft - n) @ anything"
  1778   let ?S = "\<lambda>nl. nl = xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything"
  1788   let ?S = "\<lambda>nl. nl = xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (?ft - Suc n) @ anything"
  1779   let ?Q1 = "\<lambda>nl. nl = xs @ 0 \<up> (?ft - n) @  x # anything"
  1789   let ?Q1 = "\<lambda>nl. nl = xs @ 0 \<up> (?ft - n) @  x # anything"
  1780   show "{?P} (?A [+] (?B [+] (?C [+] (?D [+] ?E @ ?F)))) {?S}"
  1790   show "{?P} (?A [+] (?B [+] (?C [+] (?D [+] ?E @ ?F)))) {?S}"
  1781   proof(rule_tac abc_Hoare_plus_halt)
  1791   proof(rule_tac abc_Hoare_plus_halt)
  1782     show "{?P} ?A {?Q1}"
  1792     show "{?P} ?A {?Q1}"
  1783       using len by simp
  1793       using len by simp
  1784   next
  1794   next
  1785     let ?Q2 = "\<lambda>nl. nl = xs @ rec_eval f xs # 0 \<up> (?ft - Suc n) @  x # anything"
  1795     let ?Q2 = "\<lambda>nl. nl = xs @ rec_exec f xs # 0 \<up> (?ft - Suc n) @  x # anything"
  1786     have a: "?ft \<ge> fft"
  1796     have a: "?ft \<ge> fft"
  1787       by arith
  1797       by arith
  1788     have b: "far = n"
  1798     have b: "far = n"
  1789       using compile1 termi_f len
  1799       using compile1 termi_f len
  1790       by(drule_tac param_pattern, auto)
  1800       by(drule_tac param_pattern, auto)
  1792       using compile1
  1802       using compile1
  1793       by(simp add: footprint_ge)
  1803       by(simp add: footprint_ge)
  1794     show "{?Q1} (?B [+] (?C [+] (?D [+] ?E @ ?F))) {?S}"
  1804     show "{?Q1} (?B [+] (?C [+] (?D [+] ?E @ ?F))) {?S}"
  1795     proof(rule_tac abc_Hoare_plus_halt)
  1805     proof(rule_tac abc_Hoare_plus_halt)
  1796       have "{\<lambda>nl. nl = xs @ 0 \<up> (fft - far) @ 0\<up>(?ft - fft) @ x # anything} fap 
  1806       have "{\<lambda>nl. nl = xs @ 0 \<up> (fft - far) @ 0\<up>(?ft - fft) @ x # anything} fap 
  1797             {\<lambda>nl. nl = xs @ rec_eval f xs # 0 \<up> (fft - Suc far) @ 0\<up>(?ft - fft) @ x # anything}"
  1807             {\<lambda>nl. nl = xs @ rec_exec f xs # 0 \<up> (fft - Suc far) @ 0\<up>(?ft - fft) @ x # anything}"
  1798         by(rule_tac f_ind)
  1808         by(rule_tac f_ind)
  1799       moreover have "fft - far + ?ft - fft = ?ft - far"
  1809       moreover have "fft - far + ?ft - fft = ?ft - far"
  1800         using a b c by arith
  1810         using a b c by arith
  1801       moreover have "fft - Suc n + ?ft - fft = ?ft - Suc n"
  1811       moreover have "fft - Suc n + ?ft - fft = ?ft - Suc n"
  1802         using a b c by arith
  1812         using a b c by arith
  1803       ultimately show "{?Q1} ?B {?Q2}"
  1813       ultimately show "{?Q1} ?B {?Q2}"
  1804         using b
  1814         using b
  1805         by(simp add: replicate_merge_anywhere)
  1815         by(simp add: replicate_merge_anywhere)
  1806     next
  1816     next
  1807       let ?Q3 = "\<lambda> nl. nl = xs @ 0 # rec_eval f xs # 0\<up>(?ft - Suc (Suc n)) @ x # anything"
  1817       let ?Q3 = "\<lambda> nl. nl = xs @ 0 # rec_exec f xs # 0\<up>(?ft - Suc (Suc n)) @ x # anything"
  1808       show "{?Q2} (?C [+] (?D [+] ?E @ ?F)) {?S}"
  1818       show "{?Q2} (?C [+] (?D [+] ?E @ ?F)) {?S}"
  1809       proof(rule_tac abc_Hoare_plus_halt)
  1819       proof(rule_tac abc_Hoare_plus_halt)
  1810         show "{?Q2} (?C) {?Q3}"
  1820         show "{?Q2} (?C) {?Q3}"
  1811           using mv_box_correct[of n "Suc n" "xs @ rec_eval f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ x # anything"]
  1821           using mv_box_correct[of n "Suc n" "xs @ rec_exec f xs # 0 \<up> (max (n + 3) (max fft gft) - Suc n) @ x # anything"]
  1812           using len
  1822           using len
  1813           by(auto)
  1823           by(auto)
  1814       next
  1824       next
  1815         show "{?Q3} (?D [+] ?E @ ?F) {?S}"
  1825         show "{?Q3} (?D [+] ?E @ ?F) {?S}"
  1816           using pr_loop_correct[of x x xs n g  gap gar gft f fft anything] assms
  1826           using pr_loop_correct[of x x xs n g  gap gar gft f fft anything] assms
  1817           by(simp add: rec_eval_pr_0_simps)
  1827           by(simp add: rec_exec_pr_0_simps)
  1818       qed
  1828       qed
  1819     qed
  1829     qed
  1820   qed
  1830   qed
  1821 qed 
  1831 qed 
  1822 
  1832 
  1823 lemma compile_pr_correct:
  1833 lemma compile_pr_correct:
  1824   assumes g_ind: "\<forall>y<x. terminates g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) \<and>
  1834   assumes g_ind: "\<forall>y<x. terminate g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) \<and>
  1825   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow>
  1835   (\<forall>x xa xb. rec_ci g = (x, xa, xb) \<longrightarrow>
  1826   (\<forall>xc. {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # 0 \<up> (xb - xa) @ xc} x
  1836   (\<forall>xc. {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # 0 \<up> (xb - xa) @ xc} x
  1827   {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # rec_eval g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) # 0 \<up> (xb - Suc xa) @ xc}))"
  1837   {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # rec_exec g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) # 0 \<up> (xb - Suc xa) @ xc}))"
  1828   and termi_f: "terminates f xs"
  1838   and termi_f: "terminate f xs"
  1829   and f_ind:
  1839   and f_ind:
  1830   "\<And>ap arity fp anything.
  1840   "\<And>ap arity fp anything.
  1831   rec_ci f = (ap, arity, fp) \<Longrightarrow> {\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ rec_eval f xs # 0 \<up> (fp - Suc arity) @ anything}"
  1841   rec_ci f = (ap, arity, fp) \<Longrightarrow> {\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ rec_exec f xs # 0 \<up> (fp - Suc arity) @ anything}"
  1832   and len: "length xs = n"
  1842   and len: "length xs = n"
  1833   and compile: "rec_ci (Pr n f g) = (ap, arity, fp)"
  1843   and compile: "rec_ci (Pr n f g) = (ap, arity, fp)"
  1834   shows "{\<lambda>nl. nl = xs @ x # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ x # rec_eval (Pr n f g) (xs @ [x]) # 0 \<up> (fp - Suc arity) @ anything}"
  1844   shows "{\<lambda>nl. nl = xs @ x # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ x # rec_exec (Pr n f g) (xs @ [x]) # 0 \<up> (fp - Suc arity) @ anything}"
  1835 proof(case_tac "rec_ci f", case_tac "rec_ci g")
  1845 proof(case_tac "rec_ci f", case_tac "rec_ci g")
  1836   fix fap far fft gap gar gft
  1846   fix fap far fft gap gar gft
  1837   assume h: "rec_ci f = (fap, far, fft)" "rec_ci g = (gap, gar, gft)"
  1847   assume h: "rec_ci f = (fap, far, fft)" "rec_ci g = (gap, gar, gft)"
  1838   have g: 
  1848   have g: 
  1839     "\<forall>y<x. (terminates g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) \<and>
  1849     "\<forall>y<x. (terminate g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) \<and>
  1840      (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1850      (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1841     {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # rec_eval g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything}))"
  1851     {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # rec_exec g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything}))"
  1842     using g_ind h
  1852     using g_ind h
  1843     by(auto)
  1853     by(auto)
  1844   hence termi_g: "\<forall> y<x. terminates g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])])"
  1854   hence termi_g: "\<forall> y<x. terminate g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])])"
  1845     by simp
  1855     by simp
  1846   from g have g_newind: 
  1856   from g have g_newind: 
  1847     "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1857     "\<forall> y<x. (\<forall>anything. {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # 0 \<up> (gft - gar) @ anything} gap
  1848     {\<lambda>nl. nl = xs @ y # rec_eval (Pr n f g) (xs @ [y]) # rec_eval g (xs @ [y, rec_eval (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1858     {\<lambda>nl. nl = xs @ y # rec_exec (Pr n f g) (xs @ [y]) # rec_exec g (xs @ [y, rec_exec (Pr n f g) (xs @ [y])]) # 0 \<up> (gft - Suc gar) @ anything})"
  1849     by auto
  1859     by auto
  1850   have f_newind: "\<And> anything. {\<lambda>nl. nl = xs @ 0 \<up> (fft - far) @ anything} fap {\<lambda>nl. nl = xs @ rec_eval f xs # 0 \<up> (fft - Suc far) @ anything}"
  1860   have f_newind: "\<And> anything. {\<lambda>nl. nl = xs @ 0 \<up> (fft - far) @ anything} fap {\<lambda>nl. nl = xs @ rec_exec f xs # 0 \<up> (fft - Suc far) @ anything}"
  1851     using h
  1861     using h
  1852     by(rule_tac f_ind, simp)
  1862     by(rule_tac f_ind, simp)
  1853   show "?thesis"
  1863   show "?thesis"
  1854     using termi_f termi_g h compile
  1864     using termi_f termi_g h compile
  1855     apply(simp add: rec_ci.simps abc_comp_commute, auto)
  1865     apply(simp add: rec_ci.simps abc_comp_commute, auto)
  1982   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  1992   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  1983   and ft: "ft = max (Suc arity) fft"
  1993   and ft: "ft = max (Suc arity) fft"
  1984   and len: "length xs = arity"
  1994   and len: "length xs = arity"
  1985   and far: "far = Suc arity"
  1995   and far: "far = Suc arity"
  1986   and ind: " (\<forall>xc. ({\<lambda>nl. nl = xs @ x # 0 \<up> (fft - far) @ xc} fap
  1996   and ind: " (\<forall>xc. ({\<lambda>nl. nl = xs @ x # 0 \<up> (fft - far) @ xc} fap
  1987     {\<lambda>nl. nl = xs @ x # rec_eval f (xs @ [x]) # 0 \<up> (fft - Suc far) @ xc}))"
  1997     {\<lambda>nl. nl = xs @ x # rec_exec f (xs @ [x]) # 0 \<up> (fft - Suc far) @ xc}))"
  1988   and exec_less: "rec_eval f (xs @ [x]) > 0"
  1998   and exec_less: "rec_exec f (xs @ [x]) > 0"
  1989   and compile: "rec_ci f = (fap, far, fft)"
  1999   and compile: "rec_ci f = (fap, far, fft)"
  1990   shows "\<exists> stp > 0. abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  2000   shows "\<exists> stp > 0. abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  1991     (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)"
  2001     (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)"
  1992 proof -
  2002 proof -
  1993   have "\<exists> stp. abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  2003   have "\<exists> stp. abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  1994     (length fap, xs @ x # rec_eval f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2004     (length fap, xs @ x # rec_exec f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  1995   proof -
  2005   proof -
  1996     have "\<exists> stp. abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  2006     have "\<exists> stp. abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  1997       (length fap, xs @ x # rec_eval f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2007       (length fap, xs @ x # rec_exec f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  1998     proof -
  2008     proof -
  1999       have "{\<lambda>nl. nl = xs @ x # 0 \<up> (fft - far) @ 0\<up>(ft - fft) @ anything} fap 
  2009       have "{\<lambda>nl. nl = xs @ x # 0 \<up> (fft - far) @ 0\<up>(ft - fft) @ anything} fap 
  2000             {\<lambda>nl. nl = xs @ x # rec_eval f (xs @ [x]) # 0 \<up> (fft - Suc far) @ 0\<up>(ft - fft) @ anything}"
  2010             {\<lambda>nl. nl = xs @ x # rec_exec f (xs @ [x]) # 0 \<up> (fft - Suc far) @ 0\<up>(ft - fft) @ anything}"
  2001         using ind by simp
  2011         using ind by simp
  2002       moreover have "fft > far"
  2012       moreover have "fft > far"
  2003         using compile
  2013         using compile
  2004         by(erule_tac footprint_ge)
  2014         by(erule_tac footprint_ge)
  2005       ultimately show "?thesis"
  2015       ultimately show "?thesis"
  2006         using ft far
  2016         using ft far
  2007         apply(drule_tac abc_Hoare_haltE)
  2017         apply(drule_tac abc_Hoare_haltE)
  2008         by(simp add: replicate_merge_anywhere max_absorb2)
  2018         by(simp add: replicate_merge_anywhere max_absorb2)
  2009     qed
  2019     qed
  2010     then obtain stp where "abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  2020     then obtain stp where "abc_steps_l (0, xs @ x # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  2011       (length fap, xs @ x # rec_eval f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)" ..
  2021       (length fap, xs @ x # rec_exec f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)" ..
  2012     thus "?thesis"
  2022     thus "?thesis"
  2013       by(erule_tac abc_append_frist_steps_halt_eq)
  2023       by(erule_tac abc_append_frist_steps_halt_eq)
  2014   qed
  2024   qed
  2015   moreover have 
  2025   moreover have 
  2016     "\<exists> stp > 0. abc_steps_l (length fap, xs @ x # rec_eval f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything) (fap @ B) stp =
  2026     "\<exists> stp > 0. abc_steps_l (length fap, xs @ x # rec_exec f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything) (fap @ B) stp =
  2017     (0, xs @ Suc x # 0 # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2027     (0, xs @ Suc x # 0 # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2018     using mn_correct[of f fap far fft "rec_eval f (xs @ [x])" xs arity B
  2028     using mn_correct[of f fap far fft "rec_exec f (xs @ [x])" xs arity B
  2019       "(\<lambda>stp. (abc_steps_l (length fap, xs @ x # rec_eval f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything) (fap @ B) stp, length fap, arity))"     
  2029       "(\<lambda>stp. (abc_steps_l (length fap, xs @ x # rec_exec f (xs @ [x]) # 0 \<up> (ft - Suc (Suc arity)) @ anything) (fap @ B) stp, length fap, arity))"     
  2020       x "0 \<up> (ft - Suc (Suc arity)) @ anything" "(\<lambda>((as, lm), ss, arity). as = 0)" 
  2030       x "0 \<up> (ft - Suc (Suc arity)) @ anything" "(\<lambda>((as, lm), ss, arity). as = 0)" 
  2021       "(\<lambda>((as, lm), ss, aritya). mn_ind_inv (as, lm) (length fap) x (rec_eval f (xs @ [x])) (0 \<up> (ft - Suc (Suc arity)) @ anything) xs) "]  
  2031       "(\<lambda>((as, lm), ss, aritya). mn_ind_inv (as, lm) (length fap) x (rec_exec f (xs @ [x])) (0 \<up> (ft - Suc (Suc arity)) @ anything) xs) "]  
  2022       B compile  exec_less len
  2032       B compile  exec_less len
  2023     apply(subgoal_tac "fap \<noteq> []", auto)
  2033     apply(subgoal_tac "fap \<noteq> []", auto)
  2024     apply(rule_tac x = stp in exI, auto simp: mn_ind_inv.simps)
  2034     apply(rule_tac x = stp in exI, auto simp: mn_ind_inv.simps)
  2025     by(case_tac "stp = 0", simp_all add: abc_steps_l.simps)
  2035     by(case_tac "stp = 0", simp_all add: abc_steps_l.simps)
  2026   moreover have "fft > far"
  2036   moreover have "fft > far"
  2036 lemma mn_loop_correct': 
  2046 lemma mn_loop_correct': 
  2037   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  2047   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  2038   and ft: "ft = max (Suc arity) fft"
  2048   and ft: "ft = max (Suc arity) fft"
  2039   and len: "length xs = arity"
  2049   and len: "length xs = arity"
  2040   and ind_all: "\<forall>i\<le>x. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2050   and ind_all: "\<forall>i\<le>x. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2041     {\<lambda>nl. nl = xs @ i # rec_eval f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2051     {\<lambda>nl. nl = xs @ i # rec_exec f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2042   and exec_ge: "\<forall> i\<le>x. rec_eval f (xs @ [i]) > 0"
  2052   and exec_ge: "\<forall> i\<le>x. rec_exec f (xs @ [i]) > 0"
  2043   and compile: "rec_ci f = (fap, far, fft)"
  2053   and compile: "rec_ci f = (fap, far, fft)"
  2044   and far: "far = Suc arity"
  2054   and far: "far = Suc arity"
  2045   shows "\<exists> stp > x. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = 
  2055   shows "\<exists> stp > x. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = 
  2046                (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)"
  2056                (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)"
  2047 using ind_all exec_ge
  2057 using ind_all exec_ge
  2050   thus "?case"
  2060   thus "?case"
  2051     using assms
  2061     using assms
  2052     by(rule_tac mn_loop, simp_all)
  2062     by(rule_tac mn_loop, simp_all)
  2053 next
  2063 next
  2054   case (Suc x)
  2064   case (Suc x)
  2055   have ind': "\<lbrakk>\<forall>i\<le>x. \<forall>xc. {\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap {\<lambda>nl. nl = xs @ i # rec_eval f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc};
  2065   have ind': "\<lbrakk>\<forall>i\<le>x. \<forall>xc. {\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap {\<lambda>nl. nl = xs @ i # rec_exec f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc};
  2056                \<forall>i\<le>x. 0 < rec_eval f (xs @ [i])\<rbrakk> \<Longrightarrow> 
  2066                \<forall>i\<le>x. 0 < rec_exec f (xs @ [i])\<rbrakk> \<Longrightarrow> 
  2057             \<exists>stp > x. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)" by fact
  2067             \<exists>stp > x. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)" by fact
  2058   have exec_ge: "\<forall>i\<le>Suc x. 0 < rec_eval f (xs @ [i])" by fact
  2068   have exec_ge: "\<forall>i\<le>Suc x. 0 < rec_exec f (xs @ [i])" by fact
  2059   have ind_all: "\<forall>i\<le>Suc x. \<forall>xc. {\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap 
  2069   have ind_all: "\<forall>i\<le>Suc x. \<forall>xc. {\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap 
  2060     {\<lambda>nl. nl = xs @ i # rec_eval f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}" by fact
  2070     {\<lambda>nl. nl = xs @ i # rec_exec f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}" by fact
  2061   have ind: "\<exists>stp > x. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  2071   have ind: "\<exists>stp > x. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  2062     (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)" using ind' exec_ge ind_all by simp
  2072     (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)" using ind' exec_ge ind_all by simp
  2063   have stp: "\<exists> stp > 0. abc_steps_l (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  2073   have stp: "\<exists> stp > 0. abc_steps_l (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp =
  2064     (0, xs @ Suc (Suc x) # 0 \<up> (ft - Suc arity) @ anything)"
  2074     (0, xs @ Suc (Suc x) # 0 \<up> (ft - Suc arity) @ anything)"
  2065     using ind_all exec_ge B ft len far compile
  2075     using ind_all exec_ge B ft len far compile
  2072 lemma mn_loop_correct: 
  2082 lemma mn_loop_correct: 
  2073   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  2083   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  2074   and ft: "ft = max (Suc arity) fft"
  2084   and ft: "ft = max (Suc arity) fft"
  2075   and len: "length xs = arity"
  2085   and len: "length xs = arity"
  2076   and ind_all: "\<forall>i\<le>x. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2086   and ind_all: "\<forall>i\<le>x. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2077     {\<lambda>nl. nl = xs @ i # rec_eval f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2087     {\<lambda>nl. nl = xs @ i # rec_exec f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2078   and exec_ge: "\<forall> i\<le>x. rec_eval f (xs @ [i]) > 0"
  2088   and exec_ge: "\<forall> i\<le>x. rec_exec f (xs @ [i]) > 0"
  2079   and compile: "rec_ci f = (fap, far, fft)"
  2089   and compile: "rec_ci f = (fap, far, fft)"
  2080   and far: "far = Suc arity"
  2090   and far: "far = Suc arity"
  2081   shows "\<exists> stp. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = 
  2091   shows "\<exists> stp. abc_steps_l (0, xs @ 0 # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = 
  2082                (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)"
  2092                (0, xs @ Suc x # 0 \<up> (ft - Suc arity) @ anything)"
  2083 proof -
  2093 proof -
  2090 
  2100 
  2091 lemma compile_mn_correct': 
  2101 lemma compile_mn_correct': 
  2092   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  2102   assumes B:  "B = [Dec (Suc arity) (length fap + 5), Dec (Suc arity) (length fap + 3), Goto (Suc (length fap)), Inc arity, Goto 0]"
  2093   and ft: "ft = max (Suc arity) fft"
  2103   and ft: "ft = max (Suc arity) fft"
  2094   and len: "length xs = arity"
  2104   and len: "length xs = arity"
  2095   and termi_f: "terminates f (xs @ [r])"
  2105   and termi_f: "terminate f (xs @ [r])"
  2096   and f_ind: "\<And>anything. {\<lambda>nl. nl = xs @ r # 0 \<up> (fft - far) @ anything} fap 
  2106   and f_ind: "\<And>anything. {\<lambda>nl. nl = xs @ r # 0 \<up> (fft - far) @ anything} fap 
  2097         {\<lambda>nl. nl = xs @ r # 0 # 0 \<up> (fft - Suc far) @ anything}"
  2107         {\<lambda>nl. nl = xs @ r # 0 # 0 \<up> (fft - Suc far) @ anything}"
  2098   and ind_all: "\<forall>i < r. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2108   and ind_all: "\<forall>i < r. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2099     {\<lambda>nl. nl = xs @ i # rec_eval f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2109     {\<lambda>nl. nl = xs @ i # rec_exec f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2100   and exec_less: "\<forall> i<r. rec_eval f (xs @ [i]) > 0"
  2110   and exec_less: "\<forall> i<r. rec_exec f (xs @ [i]) > 0"
  2101   and exec: "rec_eval f (xs @ [r]) = 0"
  2111   and exec: "rec_exec f (xs @ [r]) = 0"
  2102   and compile: "rec_ci f = (fap, far, fft)"
  2112   and compile: "rec_ci f = (fap, far, fft)"
  2103   shows "{\<lambda>nl. nl = xs @ 0 \<up> (max (Suc arity) fft - arity) @ anything}
  2113   shows "{\<lambda>nl. nl = xs @ 0 \<up> (max (Suc arity) fft - arity) @ anything}
  2104     fap @ B
  2114     fap @ B
  2105     {\<lambda>nl. nl = xs @ rec_eval (Mn arity f) xs # 0 \<up> (max (Suc arity) fft - Suc arity) @ anything}"
  2115     {\<lambda>nl. nl = xs @ rec_exec (Mn arity f) xs # 0 \<up> (max (Suc arity) fft - Suc arity) @ anything}"
  2106 proof -
  2116 proof -
  2107   have a: "far = Suc arity"
  2117   have a: "far = Suc arity"
  2108     using len compile termi_f
  2118     using len compile termi_f
  2109     by(drule_tac param_pattern, auto)
  2119     by(drule_tac param_pattern, auto)
  2110   have b: "fft > far"
  2120   have b: "fft > far"
  2115     using assms a
  2125     using assms a
  2116     apply(case_tac r, rule_tac x = 0 in exI, simp add: abc_steps_l.simps, simp)
  2126     apply(case_tac r, rule_tac x = 0 in exI, simp add: abc_steps_l.simps, simp)
  2117     by(rule_tac mn_loop_correct, auto)  
  2127     by(rule_tac mn_loop_correct, auto)  
  2118   moreover have 
  2128   moreover have 
  2119     "\<exists> stp. abc_steps_l (0, xs @ r # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = 
  2129     "\<exists> stp. abc_steps_l (0, xs @ r # 0 \<up> (ft - Suc arity) @ anything) (fap @ B) stp = 
  2120     (length fap, xs @ r # rec_eval f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2130     (length fap, xs @ r # rec_exec f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2121   proof -
  2131   proof -
  2122     have "\<exists> stp. abc_steps_l (0, xs @ r # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  2132     have "\<exists> stp. abc_steps_l (0, xs @ r # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  2123       (length fap, xs @ r # rec_eval f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2133       (length fap, xs @ r # rec_exec f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2124     proof -
  2134     proof -
  2125       have "{\<lambda>nl. nl = xs @ r # 0 \<up> (fft - far) @ 0\<up>(ft - fft) @ anything} fap 
  2135       have "{\<lambda>nl. nl = xs @ r # 0 \<up> (fft - far) @ 0\<up>(ft - fft) @ anything} fap 
  2126             {\<lambda>nl. nl = xs @ r # rec_eval f (xs @ [r]) # 0 \<up> (fft - Suc far) @ 0\<up>(ft - fft) @ anything}"
  2136             {\<lambda>nl. nl = xs @ r # rec_exec f (xs @ [r]) # 0 \<up> (fft - Suc far) @ 0\<up>(ft - fft) @ anything}"
  2127         using f_ind exec by simp
  2137         using f_ind exec by simp
  2128       thus "?thesis"
  2138       thus "?thesis"
  2129         using ft a b
  2139         using ft a b
  2130         apply(drule_tac abc_Hoare_haltE)
  2140         apply(drule_tac abc_Hoare_haltE)
  2131         by(simp add: replicate_merge_anywhere max_absorb2)
  2141         by(simp add: replicate_merge_anywhere max_absorb2)
  2132     qed
  2142     qed
  2133     then obtain stp where "abc_steps_l (0, xs @ r # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  2143     then obtain stp where "abc_steps_l (0, xs @ r # 0 \<up> (ft - Suc arity) @ anything) fap stp =
  2134       (length fap, xs @ r # rec_eval f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)" ..
  2144       (length fap, xs @ r # rec_exec f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)" ..
  2135     thus "?thesis"
  2145     thus "?thesis"
  2136       by(erule_tac abc_append_frist_steps_halt_eq)
  2146       by(erule_tac abc_append_frist_steps_halt_eq)
  2137   qed
  2147   qed
  2138   moreover have 
  2148   moreover have 
  2139     "\<exists> stp. abc_steps_l (length fap, xs @ r # rec_eval f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything) (fap @ B) stp = 
  2149     "\<exists> stp. abc_steps_l (length fap, xs @ r # rec_exec f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything) (fap @ B) stp = 
  2140              (length fap + 5, xs @ r # rec_eval f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2150              (length fap + 5, xs @ r # rec_exec f (xs @ [r]) # 0 \<up> (ft - Suc (Suc arity)) @ anything)"
  2141     using ft a b len B exec
  2151     using ft a b len B exec
  2142     apply(rule_tac x = 1 in exI, auto)
  2152     apply(rule_tac x = 1 in exI, auto)
  2143     by(auto simp: abc_steps_l.simps B abc_step_l.simps 
  2153     by(auto simp: abc_steps_l.simps B abc_step_l.simps 
  2144       abc_fetch.simps nth_append max_absorb2 abc_lm_v.simps abc_lm_s.simps)
  2154       abc_fetch.simps nth_append max_absorb2 abc_lm_v.simps abc_lm_s.simps)
  2145   moreover have "rec_eval (Mn (length xs) f) xs = r"
  2155   moreover have "rec_exec (Mn (length xs) f) xs = r"
  2146     using exec exec_less
  2156     using exec exec_less
  2147     apply(auto simp: rec_eval.simps Least_def)
  2157     apply(auto simp: rec_exec.simps Least_def)
  2148     thm the_equality
  2158     thm the_equality
  2149     apply(rule_tac the_equality, auto)
  2159     apply(rule_tac the_equality, auto)
  2150     apply(metis exec_less less_not_refl3 linorder_not_less)
  2160     apply(metis exec_less less_not_refl3 linorder_not_less)
  2151     by (metis le_neq_implies_less less_not_refl3)
  2161     by (metis le_neq_implies_less less_not_refl3)
  2152   ultimately show "?thesis"
  2162   ultimately show "?thesis"
  2156     by(simp add: abc_steps_add replicate_Suc_iff_anywhere max_absorb2 Suc_diff_Suc del: replicate_Suc)
  2166     by(simp add: abc_steps_add replicate_Suc_iff_anywhere max_absorb2 Suc_diff_Suc del: replicate_Suc)
  2157 qed
  2167 qed
  2158 
  2168 
  2159 lemma compile_mn_correct:
  2169 lemma compile_mn_correct:
  2160   assumes len: "length xs = n"
  2170   assumes len: "length xs = n"
  2161   and termi_f: "terminates f (xs @ [r])"
  2171   and termi_f: "terminate f (xs @ [r])"
  2162   and f_ind: "\<And>ap arity fp anything. rec_ci f = (ap, arity, fp) \<Longrightarrow> 
  2172   and f_ind: "\<And>ap arity fp anything. rec_ci f = (ap, arity, fp) \<Longrightarrow> 
  2163   {\<lambda>nl. nl = xs @ r # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ r # 0 # 0 \<up> (fp - Suc arity) @ anything}"
  2173   {\<lambda>nl. nl = xs @ r # 0 \<up> (fp - arity) @ anything} ap {\<lambda>nl. nl = xs @ r # 0 # 0 \<up> (fp - Suc arity) @ anything}"
  2164   and exec: "rec_eval f (xs @ [r]) = 0"
  2174   and exec: "rec_exec f (xs @ [r]) = 0"
  2165   and ind_all: 
  2175   and ind_all: 
  2166   "\<forall>i<r. terminates f (xs @ [i]) \<and>
  2176   "\<forall>i<r. terminate f (xs @ [i]) \<and>
  2167   (\<forall>x xa xb. rec_ci f = (x, xa, xb) \<longrightarrow> 
  2177   (\<forall>x xa xb. rec_ci f = (x, xa, xb) \<longrightarrow> 
  2168   (\<forall>xc. {\<lambda>nl. nl = xs @ i # 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ i # rec_eval f (xs @ [i]) # 0 \<up> (xb - Suc xa) @ xc})) \<and>
  2178   (\<forall>xc. {\<lambda>nl. nl = xs @ i # 0 \<up> (xb - xa) @ xc} x {\<lambda>nl. nl = xs @ i # rec_exec f (xs @ [i]) # 0 \<up> (xb - Suc xa) @ xc})) \<and>
  2169   0 < rec_eval f (xs @ [i])"
  2179   0 < rec_exec f (xs @ [i])"
  2170   and compile: "rec_ci (Mn n f) = (ap, arity, fp)"
  2180   and compile: "rec_ci (Mn n f) = (ap, arity, fp)"
  2171   shows "{\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap 
  2181   shows "{\<lambda>nl. nl = xs @ 0 \<up> (fp - arity) @ anything} ap 
  2172   {\<lambda>nl. nl = xs @ rec_eval (Mn n f) xs # 0 \<up> (fp - Suc arity) @ anything}"
  2182   {\<lambda>nl. nl = xs @ rec_exec (Mn n f) xs # 0 \<up> (fp - Suc arity) @ anything}"
  2173 proof(case_tac "rec_ci f")
  2183 proof(case_tac "rec_ci f")
  2174   fix fap far fft
  2184   fix fap far fft
  2175   assume h: "rec_ci f = (fap, far, fft)"
  2185   assume h: "rec_ci f = (fap, far, fft)"
  2176   hence f_newind: 
  2186   hence f_newind: 
  2177     "\<And>anything. {\<lambda>nl. nl = xs @ r # 0 \<up> (fft - far) @ anything} fap 
  2187     "\<And>anything. {\<lambda>nl. nl = xs @ r # 0 \<up> (fft - far) @ anything} fap 
  2178         {\<lambda>nl. nl = xs @ r # 0 # 0 \<up> (fft - Suc far) @ anything}"
  2188         {\<lambda>nl. nl = xs @ r # 0 # 0 \<up> (fft - Suc far) @ anything}"
  2179     by(rule_tac f_ind, simp)
  2189     by(rule_tac f_ind, simp)
  2180   have newind_all: 
  2190   have newind_all: 
  2181     "\<forall>i < r. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2191     "\<forall>i < r. (\<forall>xc. ({\<lambda>nl. nl = xs @ i # 0 \<up> (fft - far) @ xc} fap
  2182     {\<lambda>nl. nl = xs @ i # rec_eval f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2192     {\<lambda>nl. nl = xs @ i # rec_exec f (xs @ [i]) # 0 \<up> (fft - Suc far) @ xc}))"
  2183     using ind_all h
  2193     using ind_all h
  2184     by(auto)
  2194     by(auto)
  2185   have all_less: "\<forall> i<r. rec_eval f (xs @ [i]) > 0"
  2195   have all_less: "\<forall> i<r. rec_exec f (xs @ [i]) > 0"
  2186     using ind_all by auto
  2196     using ind_all by auto
  2187   show "?thesis"
  2197   show "?thesis"
  2188     using h compile f_newind newind_all all_less len termi_f exec
  2198     using h compile f_newind newind_all all_less len termi_f exec
  2189     apply(auto simp: rec_ci.simps)
  2199     apply(auto simp: rec_ci.simps)
  2190     by(rule_tac compile_mn_correct', auto)
  2200     by(rule_tac compile_mn_correct', auto)
  2191 qed
  2201 qed
  2192     
  2202     
  2193 lemma recursive_compile_correct:
  2203 lemma recursive_compile_correct:
  2194    "\<lbrakk>terminates recf args; rec_ci recf = (ap, arity, fp)\<rbrakk>
  2204    "\<lbrakk>terminate recf args; rec_ci recf = (ap, arity, fp)\<rbrakk>
  2195   \<Longrightarrow> {\<lambda> nl. nl = args @ 0\<up>(fp - arity) @ anything} ap 
  2205   \<Longrightarrow> {\<lambda> nl. nl = args @ 0\<up>(fp - arity) @ anything} ap 
  2196          {\<lambda> nl. nl = args@ rec_eval recf args # 0\<up>(fp - Suc arity) @ anything}"
  2206          {\<lambda> nl. nl = args@ rec_exec recf args # 0\<up>(fp - Suc arity) @ anything}"
  2197 apply(induct arbitrary: ap arity fp anything r rule: terminates.induct)
  2207 apply(induct arbitrary: ap arity fp anything r rule: terminate.induct)
  2198 apply(simp_all add: compile_s_correct compile_z_correct compile_id_correct 
  2208 apply(simp_all add: compile_s_correct compile_z_correct compile_id_correct 
  2199                     compile_cn_correct compile_pr_correct compile_mn_correct)
  2209                     compile_cn_correct compile_pr_correct compile_mn_correct)
  2200 done
  2210 done
  2201 
  2211 
  2202 definition dummy_abc :: "nat \<Rightarrow> abc_inst list"
  2212 definition dummy_abc :: "nat \<Rightarrow> abc_inst list"
  2321     by auto
  2331     by auto
  2322 qed
  2332 qed
  2323 
  2333 
  2324 lemma recursive_compile_correct_norm': 
  2334 lemma recursive_compile_correct_norm': 
  2325   "\<lbrakk>rec_ci f = (ap, arity, ft);  
  2335   "\<lbrakk>rec_ci f = (ap, arity, ft);  
  2326     terminates f args\<rbrakk>
  2336     terminate f args\<rbrakk>
  2327   \<Longrightarrow> \<exists> stp rl. (abc_steps_l (0, args) ap stp) = (length ap, rl) \<and> abc_list_crsp (args @ [rec_eval f args]) rl"
  2337   \<Longrightarrow> \<exists> stp rl. (abc_steps_l (0, args) ap stp) = (length ap, rl) \<and> abc_list_crsp (args @ [rec_exec f args]) rl"
  2328   using recursive_compile_correct[of f args ap arity ft "[]"]
  2338   using recursive_compile_correct[of f args ap arity ft "[]"]
  2329 apply(auto simp: abc_Hoare_halt_def)
  2339 apply(auto simp: abc_Hoare_halt_def)
  2330 apply(rule_tac x = n in exI)
  2340 apply(rule_tac x = n in exI)
  2331 apply(case_tac "abc_steps_l (0, args @ 0 \<up> (ft - arity)) ap n", auto)
  2341 apply(case_tac "abc_steps_l (0, args @ 0 \<up> (ft - arity)) ap n", auto)
  2332 apply(drule_tac abc_list_crsp_steps, auto)
  2342 apply(drule_tac abc_list_crsp_steps, auto)
  2333 apply(rule_tac list_crsp_simp2, auto)
  2343 apply(rule_tac list_crsp_simp2, auto)
  2334 done
  2344 done
  2335 
  2345 
  2336 lemma [simp]:
  2346 lemma [simp]:
  2337   assumes a: "args @ [rec_eval f args] = lm @ 0 \<up> n"
  2347   assumes a: "args @ [rec_exec f args] = lm @ 0 \<up> n"
  2338   and b: "length args < length lm"
  2348   and b: "length args < length lm"
  2339   shows "\<exists>m. lm = args @ rec_eval f args # 0 \<up> m"
  2349   shows "\<exists>m. lm = args @ rec_exec f args # 0 \<up> m"
  2340 using assms
  2350 using assms
  2341 apply(case_tac n, simp)
  2351 apply(case_tac n, simp)
  2342 apply(rule_tac x = 0 in exI, simp)
  2352 apply(rule_tac x = 0 in exI, simp)
  2343 apply(drule_tac length_equal, simp)
  2353 apply(drule_tac length_equal, simp)
  2344 done
  2354 done
  2345 
  2355 
  2346 lemma [simp]: 
  2356 lemma [simp]: 
  2347 "\<lbrakk>args @ [rec_eval f args] = lm @ 0 \<up> n; \<not> length args < length lm\<rbrakk>
  2357 "\<lbrakk>args @ [rec_exec f args] = lm @ 0 \<up> n; \<not> length args < length lm\<rbrakk>
  2348   \<Longrightarrow> \<exists>m. (lm @ 0 \<up> (length args - length lm) @ [Suc 0])[length args := 0] =
  2358   \<Longrightarrow> \<exists>m. (lm @ 0 \<up> (length args - length lm) @ [Suc 0])[length args := 0] =
  2349   args @ rec_eval f args # 0 \<up> m"
  2359   args @ rec_exec f args # 0 \<up> m"
  2350 apply(case_tac n, simp_all add: exp_suc list_update_append list_update.simps del: replicate_Suc)
  2360 apply(case_tac n, simp_all add: exp_suc list_update_append list_update.simps del: replicate_Suc)
  2351 apply(subgoal_tac "length args = Suc (length lm)", simp)
  2361 apply(subgoal_tac "length args = Suc (length lm)", simp)
  2352 apply(rule_tac x = "Suc (Suc 0)" in exI, simp)
  2362 apply(rule_tac x = "Suc (Suc 0)" in exI, simp)
  2353 apply(drule_tac length_equal, simp, auto)
  2363 apply(drule_tac length_equal, simp, auto)
  2354 done
  2364 done
  2355 
  2365 
  2356 lemma compile_append_dummy_correct: 
  2366 lemma compile_append_dummy_correct: 
  2357   assumes compile: "rec_ci f = (ap, ary, fp)"
  2367   assumes compile: "rec_ci f = (ap, ary, fp)"
  2358   and termi: "terminates f args"
  2368   and termi: "terminate f args"
  2359   shows "{\<lambda> nl. nl = args} (ap [+] dummy_abc (length args)) {\<lambda> nl. (\<exists> m. nl = args @ rec_eval f args # 0\<up>m)}"
  2369   shows "{\<lambda> nl. nl = args} (ap [+] dummy_abc (length args)) {\<lambda> nl. (\<exists> m. nl = args @ rec_exec f args # 0\<up>m)}"
  2360 proof(rule_tac abc_Hoare_plus_halt)
  2370 proof(rule_tac abc_Hoare_plus_halt)
  2361   show "{\<lambda>nl. nl = args} ap {\<lambda> nl. abc_list_crsp (args @ [rec_eval f args]) nl}"
  2371   show "{\<lambda>nl. nl = args} ap {\<lambda> nl. abc_list_crsp (args @ [rec_exec f args]) nl}"
  2362     using compile termi recursive_compile_correct_norm'[of f ap ary fp args]
  2372     using compile termi recursive_compile_correct_norm'[of f ap ary fp args]
  2363     apply(auto simp: abc_Hoare_halt_def)
  2373     apply(auto simp: abc_Hoare_halt_def)
  2364     by(rule_tac x = stp in exI, simp)
  2374     by(rule_tac x = stp in exI, simp)
  2365 next
  2375 next
  2366   show "{abc_list_crsp (args @ [rec_eval f args])} dummy_abc (length args) 
  2376   show "{abc_list_crsp (args @ [rec_exec f args])} dummy_abc (length args) 
  2367     {\<lambda>nl. \<exists>m. nl = args @ rec_eval f args # 0 \<up> m}"
  2377     {\<lambda>nl. \<exists>m. nl = args @ rec_exec f args # 0 \<up> m}"
  2368     apply(auto simp: dummy_abc_def abc_Hoare_halt_def)
  2378     apply(auto simp: dummy_abc_def abc_Hoare_halt_def)
  2369     apply(rule_tac x = 3 in exI)
  2379     apply(rule_tac x = 3 in exI)
  2370     by(auto simp: abc_steps_l.simps abc_list_crsp_def abc_step_l.simps numeral_3_eq_3 abc_fetch.simps
  2380     by(auto simp: abc_steps_l.simps abc_list_crsp_def abc_step_l.simps numeral_3_eq_3 abc_fetch.simps
  2371                      abc_lm_v.simps nth_append abc_lm_s.simps)
  2381                      abc_lm_v.simps nth_append abc_lm_s.simps)
  2372 qed
  2382 qed
  2384   assumes compile1: "rec_ci (Cn n f gs) = (ap, ar, ft) \<and> length args = ar"
  2394   assumes compile1: "rec_ci (Cn n f gs) = (ap, ar, ft) \<and> length args = ar"
  2385   and g: "i < length gs"
  2395   and g: "i < length gs"
  2386   and compile2: "rec_ci (gs!i) = (gap, gar, gft) \<and> gar = length args"
  2396   and compile2: "rec_ci (gs!i) = (gap, gar, gft) \<and> gar = length args"
  2387   and g_unhalt: "\<And> anything. {\<lambda> nl. nl = args @ 0\<up>(gft - gar) @ anything} gap \<up>"
  2397   and g_unhalt: "\<And> anything. {\<lambda> nl. nl = args @ 0\<up>(gft - gar) @ anything} gap \<up>"
  2388   and g_ind: "\<And> apj arj ftj j anything. \<lbrakk>j < i; rec_ci (gs!j) = (apj, arj, ftj)\<rbrakk> 
  2398   and g_ind: "\<And> apj arj ftj j anything. \<lbrakk>j < i; rec_ci (gs!j) = (apj, arj, ftj)\<rbrakk> 
  2389   \<Longrightarrow> {\<lambda> nl. nl = args @ 0\<up>(ftj - arj) @ anything} apj {\<lambda> nl. nl = args @ rec_eval (gs!j) args # 0\<up>(ftj - Suc arj) @ anything}"
  2399   \<Longrightarrow> {\<lambda> nl. nl = args @ 0\<up>(ftj - arj) @ anything} apj {\<lambda> nl. nl = args @ rec_exec (gs!j) args # 0\<up>(ftj - Suc arj) @ anything}"
  2390   and all_termi: "\<forall> j<i. terminates (gs!j) args"
  2400   and all_termi: "\<forall> j<i. terminate (gs!j) args"
  2391   shows "{\<lambda> nl. nl = args @ 0\<up>(ft - ar) @ anything} ap \<up>"
  2401   shows "{\<lambda> nl. nl = args @ 0\<up>(ft - ar) @ anything} ap \<up>"
  2392 using compile1
  2402 using compile1
  2393 apply(case_tac "rec_ci f", auto simp: rec_ci.simps abc_comp_commute)
  2403 apply(case_tac "rec_ci f", auto simp: rec_ci.simps abc_comp_commute)
  2394 proof(rule_tac abc_Hoare_plus_unhalt1)
  2404 proof(rule_tac abc_Hoare_plus_unhalt1)
  2395   fix fap far fft
  2405   fix fap far fft
  2396   let ?ft = "max (Suc (length args)) (Max (insert fft ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  2406   let ?ft = "max (Suc (length args)) (Max (insert fft ((\<lambda>(aprog, p, n). n) ` rec_ci ` set gs)))"
  2397   let ?Q = "\<lambda>nl. nl = args @ 0\<up> (?ft - length args) @ map (\<lambda>i. rec_eval i args) (take i gs) @ 
  2407   let ?Q = "\<lambda>nl. nl = args @ 0\<up> (?ft - length args) @ map (\<lambda>i. rec_exec i args) (take i gs) @ 
  2398     0\<up>(length gs - i) @ 0\<up> Suc (length args) @ anything"
  2408     0\<up>(length gs - i) @ 0\<up> Suc (length args) @ anything"
  2399   have "cn_merge_gs (map rec_ci gs) ?ft = 
  2409   have "cn_merge_gs (map rec_ci gs) ?ft = 
  2400     cn_merge_gs (map rec_ci (take i gs)) ?ft [+] (gap [+] 
  2410     cn_merge_gs (map rec_ci (take i gs)) ?ft [+] (gap [+] 
  2401     mv_box gar (?ft + i)) [+]  cn_merge_gs (map rec_ci (drop (Suc i) gs)) (?ft + Suc i)"
  2411     mv_box gar (?ft + i)) [+]  cn_merge_gs (map rec_ci (drop (Suc i) gs)) (?ft + Suc i)"
  2402     using g compile2 cn_merge_gs_split by simp
  2412     using g compile2 cn_merge_gs_split by simp
  2403   thus "{\<lambda>nl. nl = args @ 0 # 0 \<up> (?ft + length gs) @ anything} (cn_merge_gs (map rec_ci gs) ?ft) \<up>"
  2413   thus "{\<lambda>nl. nl = args @ 0 # 0 \<up> (?ft + length gs) @ anything} (cn_merge_gs (map rec_ci gs) ?ft) \<up>"
  2404   proof(simp, rule_tac abc_Hoare_plus_unhalt1, rule_tac abc_Hoare_plus_unhalt2, 
  2414   proof(simp, rule_tac abc_Hoare_plus_unhalt1, rule_tac abc_Hoare_plus_unhalt2, 
  2405               rule_tac abc_Hoare_plus_unhalt1)
  2415               rule_tac abc_Hoare_plus_unhalt1)
  2406     let ?Q_tmp = "\<lambda>nl. nl = args @ 0\<up> (gft - gar) @ 0\<up>(?ft - (length args) - (gft -gar)) @ map (\<lambda>i. rec_eval i args) (take i gs) @ 
  2416     let ?Q_tmp = "\<lambda>nl. nl = args @ 0\<up> (gft - gar) @ 0\<up>(?ft - (length args) - (gft -gar)) @ map (\<lambda>i. rec_exec i args) (take i gs) @ 
  2407       0\<up>(length gs - i) @ 0\<up> Suc (length args) @ anything"
  2417       0\<up>(length gs - i) @ 0\<up> Suc (length args) @ anything"
  2408     have a: "{?Q_tmp} gap \<up>"
  2418     have a: "{?Q_tmp} gap \<up>"
  2409       using g_unhalt[of "0 \<up> (?ft - (length args) - (gft - gar)) @
  2419       using g_unhalt[of "0 \<up> (?ft - (length args) - (gft - gar)) @
  2410         map (\<lambda>i. rec_eval i args) (take i gs) @ 0 \<up> (length gs - i) @ 0 \<up> Suc (length args) @ anything"]
  2420         map (\<lambda>i. rec_exec i args) (take i gs) @ 0 \<up> (length gs - i) @ 0 \<up> Suc (length args) @ anything"]
  2411       by simp
  2421       by simp
  2412     moreover have "?ft \<ge> gft"
  2422     moreover have "?ft \<ge> gft"
  2413       using g compile2
  2423       using g compile2
  2414       apply(rule_tac min_max.le_supI2, rule_tac Max_ge, simp, rule_tac insertI2)
  2424       apply(rule_tac min_max.le_supI2, rule_tac Max_ge, simp, rule_tac insertI2)
  2415       apply(rule_tac  x = "rec_ci (gs ! i)" in image_eqI, simp)
  2425       apply(rule_tac  x = "rec_ci (gs ! i)" in image_eqI, simp)
  2422       using a by simp
  2432       using a by simp
  2423   next
  2433   next
  2424     show "{\<lambda>nl. nl = args @ 0 # 0 \<up> (?ft + length gs) @ anything} 
  2434     show "{\<lambda>nl. nl = args @ 0 # 0 \<up> (?ft + length gs) @ anything} 
  2425       cn_merge_gs (map rec_ci (take i gs)) ?ft
  2435       cn_merge_gs (map rec_ci (take i gs)) ?ft
  2426        {\<lambda>nl. nl = args @ 0 \<up> (?ft - length args) @
  2436        {\<lambda>nl. nl = args @ 0 \<up> (?ft - length args) @
  2427       map (\<lambda>i. rec_eval i args) (take i gs) @ 0 \<up> (length gs - i) @ 0 \<up> Suc (length args) @ anything}"
  2437       map (\<lambda>i. rec_exec i args) (take i gs) @ 0 \<up> (length gs - i) @ 0 \<up> Suc (length args) @ anything}"
  2428       using all_termi
  2438       using all_termi
  2429       apply(rule_tac compile_cn_gs_correct', auto simp: set_conv_nth)
  2439       apply(rule_tac compile_cn_gs_correct', auto simp: set_conv_nth)
  2430       by(drule_tac apj = x and arj = xa and  ftj = xb and j = ia and anything = xc in g_ind, auto)
  2440       by(drule_tac apj = x and arj = xa and  ftj = xb and j = ia and anything = xc in g_ind, auto)
  2431   qed
  2441   qed
  2432 qed
  2442 qed
  2433 
  2443 
  2434 
  2444 
  2435 
  2445 
  2436 lemma mn_unhalt_case':
  2446 lemma mn_unhalt_case':
  2437   assumes compile: "rec_ci f = (a, b, c)"
  2447   assumes compile: "rec_ci f = (a, b, c)"
  2438   and all_termi: "\<forall>i. terminates f (args @ [i]) \<and> 0 < rec_eval f (args @ [i])"
  2448   and all_termi: "\<forall>i. terminate f (args @ [i]) \<and> 0 < rec_exec f (args @ [i])"
  2439   and B: "B = [Dec (Suc (length args)) (length a + 5), Dec (Suc (length args)) (length a + 3), 
  2449   and B: "B = [Dec (Suc (length args)) (length a + 5), Dec (Suc (length args)) (length a + 3), 
  2440   Goto (Suc (length a)), Inc (length args), Goto 0]"
  2450   Goto (Suc (length a)), Inc (length args), Goto 0]"
  2441   shows "{\<lambda>nl. nl = args @ 0 \<up> (max (Suc (length args)) c - length args) @ anything}
  2451   shows "{\<lambda>nl. nl = args @ 0 \<up> (max (Suc (length args)) c - length args) @ anything}
  2442   a @ B \<up>"
  2452   a @ B \<up>"
  2443 proof(rule_tac abc_Hoare_unhaltI, auto)
  2453 proof(rule_tac abc_Hoare_unhaltI, auto)
  2453          = (0, args @ Suc n # 0\<up>(c - Suc (length args)) @ anything)"
  2463          = (0, args @ Suc n # 0\<up>(c - Suc (length args)) @ anything)"
  2454     using assms a b c
  2464     using assms a b c
  2455   proof(rule_tac mn_loop_correct', auto)
  2465   proof(rule_tac mn_loop_correct', auto)
  2456     fix i xc
  2466     fix i xc
  2457     show "{\<lambda>nl. nl = args @ i # 0 \<up> (c - Suc (length args)) @ xc} a 
  2467     show "{\<lambda>nl. nl = args @ i # 0 \<up> (c - Suc (length args)) @ xc} a 
  2458       {\<lambda>nl. nl = args @ i # rec_eval f (args @ [i]) # 0 \<up> (c - Suc (Suc (length args))) @ xc}"
  2468       {\<lambda>nl. nl = args @ i # rec_exec f (args @ [i]) # 0 \<up> (c - Suc (Suc (length args))) @ xc}"
  2459       using all_termi recursive_compile_correct[of f "args @ [i]" a b c xc] compile a
  2469       using all_termi recursive_compile_correct[of f "args @ [i]" a b c xc] compile a
  2460       by(simp)
  2470       by(simp)
  2461   qed
  2471   qed
  2462   then obtain stp where d: "stp > n \<and> abc_steps_l (0, args @ 0 # 0\<up>(c - Suc (length args)) @ anything) (a @ B) stp
  2472   then obtain stp where d: "stp > n \<and> abc_steps_l (0, args @ 0 # 0\<up>(c - Suc (length args)) @ anything) (a @ B) stp
  2463          = (0, args @ Suc n # 0\<up>(c - Suc (length args)) @ anything)" ..
  2473          = (0, args @ Suc n # 0\<up>(c - Suc (length args)) @ anything)" ..
  2475     by(simp add: replicate_Suc_iff_anywhere Suc_diff_Suc del: replicate_Suc)
  2485     by(simp add: replicate_Suc_iff_anywhere Suc_diff_Suc del: replicate_Suc)
  2476 qed
  2486 qed
  2477     
  2487     
  2478 lemma mn_unhalt_case: 
  2488 lemma mn_unhalt_case: 
  2479   assumes compile: "rec_ci (Mn n f) = (ap, ar, ft) \<and> length args = ar"
  2489   assumes compile: "rec_ci (Mn n f) = (ap, ar, ft) \<and> length args = ar"
  2480   and all_term: "\<forall> i. terminates f (args @ [i]) \<and> rec_eval f (args @ [i]) > 0"
  2490   and all_term: "\<forall> i. terminate f (args @ [i]) \<and> rec_exec f (args @ [i]) > 0"
  2481   shows "{\<lambda> nl. nl = args @ 0\<up>(ft - ar) @ anything} ap \<up> "
  2491   shows "{\<lambda> nl. nl = args @ 0\<up>(ft - ar) @ anything} ap \<up> "
  2482   using assms
  2492   using assms
  2483 apply(case_tac "rec_ci f", auto simp: rec_ci.simps abc_comp_commute)
  2493 apply(case_tac "rec_ci f", auto simp: rec_ci.simps abc_comp_commute)
  2484 by(rule_tac mn_unhalt_case', simp_all)
  2494 by(rule_tac mn_unhalt_case', simp_all)
  2485 
  2495 
  2488                          let tp = tm_of (ap [+] dummy_abc k) in 
  2498                          let tp = tm_of (ap [+] dummy_abc k) in 
  2489                            tp @ (shift (mopup k) (length tp div 2)))"
  2499                            tp @ (shift (mopup k) (length tp div 2)))"
  2490 
  2500 
  2491 lemma recursive_compile_to_tm_correct1: 
  2501 lemma recursive_compile_to_tm_correct1: 
  2492   assumes  compile: "rec_ci recf = (ap, ary, fp)"
  2502   assumes  compile: "rec_ci recf = (ap, ary, fp)"
  2493   and termi: " terminates recf args"
  2503   and termi: " terminate recf args"
  2494   and tp: "tp = tm_of (ap [+] dummy_abc (length args))"
  2504   and tp: "tp = tm_of (ap [+] dummy_abc (length args))"
  2495   shows "\<exists> stp m l. steps0 (Suc 0, Bk # Bk # ires, <args> @ Bk\<up>rn)
  2505   shows "\<exists> stp m l. steps0 (Suc 0, Bk # Bk # ires, <args> @ Bk\<up>rn)
  2496   (tp @ shift (mopup (length args)) (length tp div 2)) stp = (0, Bk\<up>m @ Bk # Bk # ires, Oc\<up>Suc (rec_eval recf args) @ Bk\<up>l)"
  2506   (tp @ shift (mopup (length args)) (length tp div 2)) stp = (0, Bk\<up>m @ Bk # Bk # ires, Oc\<up>Suc (rec_exec recf args) @ Bk\<up>l)"
  2497 proof -
  2507 proof -
  2498   have "{\<lambda>nl. nl = args} ap [+] dummy_abc (length args) {\<lambda>nl. \<exists>m. nl = args @ rec_eval recf args # 0 \<up> m}"
  2508   have "{\<lambda>nl. nl = args} ap [+] dummy_abc (length args) {\<lambda>nl. \<exists>m. nl = args @ rec_exec recf args # 0 \<up> m}"
  2499     using compile termi compile
  2509     using compile termi compile
  2500     by(rule_tac compile_append_dummy_correct, auto)
  2510     by(rule_tac compile_append_dummy_correct, auto)
  2501   then obtain stp m where h: "abc_steps_l (0, args) (ap [+] dummy_abc (length args)) stp = 
  2511   then obtain stp m where h: "abc_steps_l (0, args) (ap [+] dummy_abc (length args)) stp = 
  2502     (length (ap [+] dummy_abc (length args)), args @ rec_eval recf args # 0\<up>m) "
  2512     (length (ap [+] dummy_abc (length args)), args @ rec_exec recf args # 0\<up>m) "
  2503     apply(simp add: abc_Hoare_halt_def, auto)
  2513     apply(simp add: abc_Hoare_halt_def, auto)
  2504     by(case_tac "abc_steps_l (0, args) (ap [+] dummy_abc (length args)) n", auto)
  2514     by(case_tac "abc_steps_l (0, args) (ap [+] dummy_abc (length args)) n", auto)
  2505   thus "?thesis"
  2515   thus "?thesis"
  2506     using assms tp
  2516     using assms tp
  2507     by(rule_tac  lm = args and stp = stp and am = "args @ rec_eval recf args # 0 \<up> m"
  2517     by(rule_tac  lm = args and stp = stp and am = "args @ rec_exec recf args # 0 \<up> m"
  2508       in compile_correct_halt, auto simp: crsp.simps start_of.simps length_abc_comp abc_lm_v.simps)
  2518       in compile_correct_halt, auto simp: crsp.simps start_of.simps length_abc_comp abc_lm_v.simps)
  2509 qed
  2519 qed
  2510 
  2520 
  2511 lemma recursive_compile_to_tm_correct2: 
  2521 lemma recursive_compile_to_tm_correct2: 
  2512   assumes termi: " terminates recf args"
  2522   assumes termi: " terminate recf args"
  2513   shows "\<exists> stp m l. steps0 (Suc 0, [Bk, Bk], <args>) (tm_of_rec recf) stp = 
  2523   shows "\<exists> stp m l. steps0 (Suc 0, [Bk, Bk], <args>) (tm_of_rec recf) stp = 
  2514                      (0, Bk\<up>Suc (Suc m), Oc\<up>Suc (rec_eval recf args) @ Bk\<up>l)"
  2524                      (0, Bk\<up>Suc (Suc m), Oc\<up>Suc (rec_exec recf args) @ Bk\<up>l)"
  2515 proof(case_tac "rec_ci recf", simp add: tm_of_rec.simps)
  2525 proof(case_tac "rec_ci recf", simp add: tm_of_rec.simps)
  2516   fix ap ar fp
  2526   fix ap ar fp
  2517   assume "rec_ci recf = (ap, ar, fp)"
  2527   assume "rec_ci recf = (ap, ar, fp)"
  2518   thus "\<exists>stp m l. steps0 (Suc 0, [Bk, Bk], <args>) 
  2528   thus "\<exists>stp m l. steps0 (Suc 0, [Bk, Bk], <args>) 
  2519     (tm_of (ap [+] dummy_abc ar) @ shift (mopup ar) (listsum (layout_of (ap [+] dummy_abc ar)))) stp =
  2529     (tm_of (ap [+] dummy_abc ar) @ shift (mopup ar) (listsum (layout_of (ap [+] dummy_abc ar)))) stp =
  2520     (0, Bk # Bk # Bk \<up> m, Oc # Oc \<up> rec_eval recf args @ Bk \<up> l)"
  2530     (0, Bk # Bk # Bk \<up> m, Oc # Oc \<up> rec_exec recf args @ Bk \<up> l)"
  2521     using recursive_compile_to_tm_correct1[of recf ap ar fp args "tm_of (ap [+] dummy_abc (length args))" "[]" 0]
  2531     using recursive_compile_to_tm_correct1[of recf ap ar fp args "tm_of (ap [+] dummy_abc (length args))" "[]" 0]
  2522       assms param_pattern[of recf args ap ar fp]
  2532       assms param_pattern[of recf args ap ar fp]
  2523     by(simp add: replicate_Suc[THEN sym] replicate_Suc_iff_anywhere del: replicate_Suc tm_of_rec_def, 
  2533     by(simp add: replicate_Suc[THEN sym] replicate_Suc_iff_anywhere del: replicate_Suc tm_of_rec_def, 
  2524       simp add: exp_suc del: replicate_Suc)
  2534       simp add: exp_suc del: replicate_Suc)
  2525 qed
  2535 qed
  2526 
  2536 
  2527 lemma recursive_compile_to_tm_correct3: 
  2537 lemma recursive_compile_to_tm_correct3: 
  2528   assumes termi: "terminates recf args"
  2538   assumes termi: "terminate recf args"
  2529   shows "{\<lambda> tp. tp =([Bk, Bk], <args>)} (tm_of_rec recf) 
  2539   shows "{\<lambda> tp. tp =([Bk, Bk], <args>)} (tm_of_rec recf) 
  2530          {\<lambda> tp. \<exists> k l. tp = (Bk\<up> k, <rec_eval recf args> @ Bk \<up> l)}"
  2540          {\<lambda> tp. \<exists> k l. tp = (Bk\<up> k, <rec_exec recf args> @ Bk \<up> l)}"
  2531 using recursive_compile_to_tm_correct2[OF assms]
  2541 using recursive_compile_to_tm_correct2[OF assms]
  2532 apply(auto simp add: Hoare_halt_def)
  2542 apply(auto simp add: Hoare_halt_def)
  2533 apply(rule_tac x = stp in exI)
  2543 apply(rule_tac x = stp in exI)
  2534 apply(auto simp add: tape_of_nat_abv)
  2544 apply(auto simp add: tape_of_nat_abv)
  2535 apply(rule_tac x = "Suc (Suc m)" in exI)
  2545 apply(rule_tac x = "Suc (Suc m)" in exI)