src/HOL/IMP/Comp_Rev.thy
changeset 44890 22f665a2e91c
parent 44070 cebb7abb54b1
child 45015 fdac1e9880eb
equal deleted inserted replaced
44889:340df9f3491f 44890:22f665a2e91c
    39 
    39 
    40 lemma exec_0 [intro!]: "P \<turnstile> c \<rightarrow>^0 c" by simp
    40 lemma exec_0 [intro!]: "P \<turnstile> c \<rightarrow>^0 c" by simp
    41 
    41 
    42 lemma exec_Suc [trans]:
    42 lemma exec_Suc [trans]:
    43   "\<lbrakk> P \<turnstile> c \<rightarrow> c'; P \<turnstile> c' \<rightarrow>^n c'' \<rbrakk> \<Longrightarrow> P \<turnstile> c \<rightarrow>^(Suc n) c''" 
    43   "\<lbrakk> P \<turnstile> c \<rightarrow> c'; P \<turnstile> c' \<rightarrow>^n c'' \<rbrakk> \<Longrightarrow> P \<turnstile> c \<rightarrow>^(Suc n) c''" 
    44   by (fastsimp simp del: split_paired_Ex)
    44   by (fastforce simp del: split_paired_Ex)
    45 
    45 
    46 lemma exec_exec_n:
    46 lemma exec_exec_n:
    47   "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> \<exists>n. P \<turnstile> c \<rightarrow>^n c'"
    47   "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> \<exists>n. P \<turnstile> c \<rightarrow>^n c'"
    48   by (induct rule: exec.induct) (auto intro: exec_Suc)
    48   by (induct rule: exec.induct) (auto intro: exec_Suc)
    49     
    49     
   116   thus "succs (x#xs) n \<subseteq> ?x \<union> ?xs" ..
   116   thus "succs (x#xs) n \<subseteq> ?x \<union> ?xs" ..
   117   
   117   
   118   { fix p assume "p \<in> ?x \<or> p \<in> ?xs"
   118   { fix p assume "p \<in> ?x \<or> p \<in> ?xs"
   119     hence "p \<in> succs (x#xs) n"
   119     hence "p \<in> succs (x#xs) n"
   120     proof
   120     proof
   121       assume "p \<in> ?x" thus ?thesis by (fastsimp simp: succs_def)
   121       assume "p \<in> ?x" thus ?thesis by (fastforce simp: succs_def)
   122     next
   122     next
   123       assume "p \<in> ?xs"
   123       assume "p \<in> ?xs"
   124       then obtain i where "?isuccs p xs (1+n) i"
   124       then obtain i where "?isuccs p xs (1+n) i"
   125         unfolding succs_def by auto
   125         unfolding succs_def by auto
   126       hence "?isuccs p (x#xs) n (1+i)"
   126       hence "?isuccs p (x#xs) n (1+i)"
   136   shows "fst c' \<in> succs P 0"
   136   shows "fst c' \<in> succs P 0"
   137   using assms by (auto elim!: iexec1.cases simp: succs_def isuccs_def)
   137   using assms by (auto elim!: iexec1.cases simp: succs_def isuccs_def)
   138 
   138 
   139 lemma succs_shift:
   139 lemma succs_shift:
   140   "(p - n \<in> succs P 0) = (p \<in> succs P n)" 
   140   "(p - n \<in> succs P 0) = (p \<in> succs P n)" 
   141   by (fastsimp simp: succs_def isuccs_def split: instr.split)
   141   by (fastforce simp: succs_def isuccs_def split: instr.split)
   142   
   142   
   143 lemma inj_op_plus [simp]:
   143 lemma inj_op_plus [simp]:
   144   "inj (op + (i::int))"
   144   "inj (op + (i::int))"
   145   by (metis add_minus_cancel inj_on_inverseI)
   145   by (metis add_minus_cancel inj_on_inverseI)
   146 
   146 
   225   case Assign thus ?case by simp
   225   case Assign thus ?case by simp
   226 next
   226 next
   227   case (Semi c1 c2)
   227   case (Semi c1 c2)
   228   from Semi.prems
   228   from Semi.prems
   229   show ?case 
   229   show ?case 
   230     by (fastsimp dest: Semi.hyps [THEN subsetD])
   230     by (fastforce dest: Semi.hyps [THEN subsetD])
   231 next
   231 next
   232   case (If b c1 c2)
   232   case (If b c1 c2)
   233   from If.prems
   233   from If.prems
   234   show ?case
   234   show ?case
   235     by (auto dest!: If.hyps [THEN subsetD] simp: isuccs_def succs_Cons)
   235     by (auto dest!: If.hyps [THEN subsetD] simp: isuccs_def succs_Cons)
   287   note split_paired_Ex [simp del]
   287   note split_paired_Ex [simp del]
   288 
   288 
   289   { assume "j0 \<in> {0 ..< isize c}"
   289   { assume "j0 \<in> {0 ..< isize c}"
   290     with j0 j rest c
   290     with j0 j rest c
   291     have ?case
   291     have ?case
   292       by (fastsimp dest!: Suc.hyps intro!: exec_Suc)
   292       by (fastforce dest!: Suc.hyps intro!: exec_Suc)
   293   } moreover {
   293   } moreover {
   294     assume "j0 \<notin> {0 ..< isize c}"
   294     assume "j0 \<notin> {0 ..< isize c}"
   295     moreover
   295     moreover
   296     from c j0 have "j0 \<in> succs c 0"
   296     from c j0 have "j0 \<in> succs c 0"
   297       by (auto dest: succs_iexec1)
   297       by (auto dest: succs_iexec1)
   298     ultimately
   298     ultimately
   299     have "j0 \<in> exits c" by (simp add: exits_def)
   299     have "j0 \<in> exits c" by (simp add: exits_def)
   300     with c j0 rest
   300     with c j0 rest
   301     have ?case by fastsimp
   301     have ?case by fastforce
   302   }
   302   }
   303   ultimately
   303   ultimately
   304   show ?case by cases
   304   show ?case by cases
   305 qed
   305 qed
   306 
   306 
   350   from step `isize P \<le> i`
   350   from step `isize P \<le> i`
   351   have "P' \<turnstile> (i - isize P, s, stk) \<rightarrow> (i' - isize P, s'', stk'')" 
   351   have "P' \<turnstile> (i - isize P, s, stk) \<rightarrow> (i' - isize P, s'', stk'')" 
   352     by (rule exec1_drop_left)
   352     by (rule exec1_drop_left)
   353   also
   353   also
   354   then have "i' - isize P \<in> succs P' 0"
   354   then have "i' - isize P \<in> succs P' 0"
   355     by (fastsimp dest!: succs_iexec1)
   355     by (fastforce dest!: succs_iexec1)
   356   with `exits P' \<subseteq> {0..}`
   356   with `exits P' \<subseteq> {0..}`
   357   have "isize P \<le> i'" by (auto simp: exits_def)
   357   have "isize P \<le> i'" by (auto simp: exits_def)
   358   from rest this `exits P' \<subseteq> {0..}`     
   358   from rest this `exits P' \<subseteq> {0..}`     
   359   have "P' \<turnstile> (i' - isize P, s'', stk'') \<rightarrow>^k (n - isize P, s', stk')"
   359   have "P' \<turnstile> (i' - isize P, s'', stk'') \<rightarrow>^k (n - isize P, s', stk')"
   360     by (rule Suc.hyps)
   360     by (rule Suc.hyps)
   381   assumes exits: "exits P' \<subseteq> {0..}"
   381   assumes exits: "exits P' \<subseteq> {0..}"
   382   shows "\<exists>k1 k2 s'' stk''. P \<turnstile> (0,s,stk) \<rightarrow>^k1 (isize P, s'', stk'') \<and> 
   382   shows "\<exists>k1 k2 s'' stk''. P \<turnstile> (0,s,stk) \<rightarrow>^k1 (isize P, s'', stk'') \<and> 
   383                            P' \<turnstile> (0,s'',stk'') \<rightarrow>^k2 (j - isize P, s', stk')"
   383                            P' \<turnstile> (0,s'',stk'') \<rightarrow>^k2 (j - isize P, s', stk')"
   384 proof (cases "P")
   384 proof (cases "P")
   385   case Nil with exec
   385   case Nil with exec
   386   show ?thesis by fastsimp
   386   show ?thesis by fastforce
   387 next
   387 next
   388   case Cons
   388   case Cons
   389   hence "0 < isize P" by simp
   389   hence "0 < isize P" by simp
   390   with exec P closed
   390   with exec P closed
   391   obtain k1 k2 s'' stk'' where
   391   obtain k1 k2 s'' stk'' where
   396   moreover
   396   moreover
   397   have "j = isize P + (j - isize P)" by simp
   397   have "j = isize P + (j - isize P)" by simp
   398   then obtain j0 where "j = isize P + j0" ..
   398   then obtain j0 where "j = isize P + j0" ..
   399   ultimately
   399   ultimately
   400   show ?thesis using exits
   400   show ?thesis using exits
   401     by (fastsimp dest: exec_n_drop_left)
   401     by (fastforce dest: exec_n_drop_left)
   402 qed
   402 qed
   403 
   403 
   404 
   404 
   405 subsection {* Correctness theorem *}
   405 subsection {* Correctness theorem *}
   406 
   406 
   422     "acomp a1 \<turnstile> (0,s,stk) \<rightarrow>^n1 (isize (acomp a1), s1, stk1)"
   422     "acomp a1 \<turnstile> (0,s,stk) \<rightarrow>^n1 (isize (acomp a1), s1, stk1)"
   423     "acomp a2 \<turnstile> (0,s1,stk1) \<rightarrow>^n2 (isize (acomp a2), s2, stk2)" 
   423     "acomp a2 \<turnstile> (0,s1,stk1) \<rightarrow>^n2 (isize (acomp a2), s2, stk2)" 
   424        "[ADD] \<turnstile> (0,s2,stk2) \<rightarrow>^n3 (1, s', stk')"
   424        "[ADD] \<turnstile> (0,s2,stk2) \<rightarrow>^n3 (1, s', stk')"
   425     by (auto dest!: exec_n_split_full)
   425     by (auto dest!: exec_n_split_full)
   426 
   426 
   427   thus ?case by (fastsimp dest: Plus.hyps simp: exec_n_simps)
   427   thus ?case by (fastforce dest: Plus.hyps simp: exec_n_simps)
   428 qed (auto simp: exec_n_simps)
   428 qed (auto simp: exec_n_simps)
   429 
   429 
   430 lemma bcomp_split:
   430 lemma bcomp_split:
   431   assumes "bcomp b c i @ P' \<turnstile> (0, s, stk) \<rightarrow>^n (j, s', stk')" 
   431   assumes "bcomp b c i @ P' \<turnstile> (0, s, stk) \<rightarrow>^n (j, s', stk')" 
   432           "j \<notin> {0..<isize (bcomp b c i)}" "0 \<le> i"
   432           "j \<notin> {0..<isize (bcomp b c i)}" "0 \<le> i"
   433   shows "\<exists>s'' stk'' i' k m. 
   433   shows "\<exists>s'' stk'' i' k m. 
   434            bcomp b c i \<turnstile> (0, s, stk) \<rightarrow>^k (i', s'', stk'') \<and>
   434            bcomp b c i \<turnstile> (0, s, stk) \<rightarrow>^k (i', s'', stk'') \<and>
   435            (i' = isize (bcomp b c i) \<or> i' = i + isize (bcomp b c i)) \<and>
   435            (i' = isize (bcomp b c i) \<or> i' = i + isize (bcomp b c i)) \<and>
   436            bcomp b c i @ P' \<turnstile> (i', s'', stk'') \<rightarrow>^m (j, s', stk') \<and>
   436            bcomp b c i @ P' \<turnstile> (i', s'', stk'') \<rightarrow>^m (j, s', stk') \<and>
   437            n = k + m"
   437            n = k + m"
   438   using assms by (cases "bcomp b c i = []") (fastsimp dest!: exec_n_drop_right)+
   438   using assms by (cases "bcomp b c i = []") (fastforce dest!: exec_n_drop_right)+
   439 
   439 
   440 lemma bcomp_exec_n [dest]:
   440 lemma bcomp_exec_n [dest]:
   441   assumes "bcomp b c j \<turnstile> (0, s, stk) \<rightarrow>^n (i, s', stk')"
   441   assumes "bcomp b c j \<turnstile> (0, s, stk) \<rightarrow>^n (i, s', stk')"
   442           "isize (bcomp b c j) \<le> i" "0 \<le> j"
   442           "isize (bcomp b c j) \<le> i" "0 \<le> j"
   443   shows "i = isize(bcomp b c j) + (if c = bval b s then j else 0) \<and>
   443   shows "i = isize(bcomp b c j) + (if c = bval b s then j else 0) \<and>
   446   case B thus ?case 
   446   case B thus ?case 
   447     by (simp split: split_if_asm add: exec_n_simps)
   447     by (simp split: split_if_asm add: exec_n_simps)
   448 next
   448 next
   449   case (Not b) 
   449   case (Not b) 
   450   from Not.prems show ?case
   450   from Not.prems show ?case
   451     by (fastsimp dest!: Not.hyps) 
   451     by (fastforce dest!: Not.hyps) 
   452 next
   452 next
   453   case (And b1 b2)
   453   case (And b1 b2)
   454   
   454   
   455   let ?b2 = "bcomp b2 c j" 
   455   let ?b2 = "bcomp b2 c j" 
   456   let ?m  = "if c then isize ?b2 else isize ?b2 + j"
   456   let ?m  = "if c then isize ?b2 else isize ?b2 + j"
   467   from b1 j
   467   from b1 j
   468   have "i' = isize ?b1 + (if \<not>bval b1 s then ?m else 0) \<and> s'' = s \<and> stk'' = stk"
   468   have "i' = isize ?b1 + (if \<not>bval b1 s then ?m else 0) \<and> s'' = s \<and> stk'' = stk"
   469     by (auto dest!: And.hyps)
   469     by (auto dest!: And.hyps)
   470   with b2 j
   470   with b2 j
   471   show ?case 
   471   show ?case 
   472     by (fastsimp dest!: And.hyps simp: exec_n_end split: split_if_asm)
   472     by (fastforce dest!: And.hyps simp: exec_n_end split: split_if_asm)
   473 next
   473 next
   474   case Less
   474   case Less
   475   thus ?case by (auto dest!: exec_n_split_full simp: exec_n_simps) (* takes time *) 
   475   thus ?case by (auto dest!: exec_n_split_full simp: exec_n_simps) (* takes time *) 
   476 qed
   476 qed
   477 
   477 
   488   case SKIP
   488   case SKIP
   489   thus ?case by auto
   489   thus ?case by auto
   490 next
   490 next
   491   case (Assign x a)
   491   case (Assign x a)
   492   thus ?case
   492   thus ?case
   493     by simp (fastsimp dest!: exec_n_split_full simp: exec_n_simps)
   493     by simp (fastforce dest!: exec_n_split_full simp: exec_n_simps)
   494 next
   494 next
   495   case (Semi c1 c2)
   495   case (Semi c1 c2)
   496   thus ?case by (fastsimp dest!: exec_n_split_full)
   496   thus ?case by (fastforce dest!: exec_n_split_full)
   497 next
   497 next
   498   case (If b c1 c2)
   498   case (If b c1 c2)
   499   note If.hyps [dest!]
   499   note If.hyps [dest!]
   500 
   500 
   501   let ?if = "IF b THEN c1 ELSE c2"
   501   let ?if = "IF b THEN c1 ELSE c2"
   516   
   516   
   517   with cs have cs':
   517   with cs have cs':
   518     "ccomp c1@JMP (isize (ccomp c2))#ccomp c2 \<turnstile> 
   518     "ccomp c1@JMP (isize (ccomp c2))#ccomp c2 \<turnstile> 
   519        (if bval b s then 0 else isize (ccomp c1)+1, s, stk) \<rightarrow>^m
   519        (if bval b s then 0 else isize (ccomp c1)+1, s, stk) \<rightarrow>^m
   520        (1 + isize (ccomp c1) + isize (ccomp c2), t, stk')"
   520        (1 + isize (ccomp c1) + isize (ccomp c2), t, stk')"
   521     by (fastsimp dest: exec_n_drop_left simp: exits_Cons isuccs_def algebra_simps)
   521     by (fastforce dest: exec_n_drop_left simp: exits_Cons isuccs_def algebra_simps)
   522      
   522      
   523   show ?case
   523   show ?case
   524   proof (cases "bval b s")
   524   proof (cases "bval b s")
   525     case True with cs'
   525     case True with cs'
   526     show ?thesis
   526     show ?thesis
   527       by simp
   527       by simp
   528          (fastsimp dest: exec_n_drop_right 
   528          (fastforce dest: exec_n_drop_right 
   529                    split: split_if_asm simp: exec_n_simps)
   529                    split: split_if_asm simp: exec_n_simps)
   530   next
   530   next
   531     case False with cs'
   531     case False with cs'
   532     show ?thesis
   532     show ?thesis
   533       by (auto dest!: exec_n_drop_Cons exec_n_drop_left 
   533       by (auto dest!: exec_n_drop_Cons exec_n_drop_left 
   543     
   543     
   544     { assume "\<not> bval b s"
   544     { assume "\<not> bval b s"
   545       with "1.prems"
   545       with "1.prems"
   546       have ?case
   546       have ?case
   547         by simp
   547         by simp
   548            (fastsimp dest!: bcomp_exec_n bcomp_split 
   548            (fastforce dest!: bcomp_exec_n bcomp_split 
   549                      simp: exec_n_simps)
   549                      simp: exec_n_simps)
   550     } moreover {
   550     } moreover {
   551       assume b: "bval b s"
   551       assume b: "bval b s"
   552       let ?c0 = "WHILE b DO c"
   552       let ?c0 = "WHILE b DO c"
   553       let ?cs = "ccomp ?c0"
   553       let ?cs = "ccomp ?c0"
   556       
   556       
   557       from "1.prems" b
   557       from "1.prems" b
   558       obtain k where
   558       obtain k where
   559         cs: "?cs \<turnstile> (isize ?bs, s, stk) \<rightarrow>^k (isize ?cs, t, stk')" and
   559         cs: "?cs \<turnstile> (isize ?bs, s, stk) \<rightarrow>^k (isize ?cs, t, stk')" and
   560         k:  "k \<le> n"
   560         k:  "k \<le> n"
   561         by (fastsimp dest!: bcomp_split)
   561         by (fastforce dest!: bcomp_split)
   562       
   562       
   563       have ?case
   563       have ?case
   564       proof cases
   564       proof cases
   565         assume "ccomp c = []"
   565         assume "ccomp c = []"
   566         with cs k
   566         with cs k