
diff -r 643fce75f6cd -r 8ed413a57bdc src/HOL/IMP/Compiler.thy
--- a/src/HOL/IMP/Compiler.thy	Thu Apr 25 17:36:29 2002 +0200
+++ b/src/HOL/IMP/Compiler.thy	Fri Apr 26 11:47:01 2002 +0200
@@ -4,46 +4,7 @@
     Copyright   1996 TUM
 *)
 
-header "A Simple Compiler"
-
-theory Compiler = Natural:
-
-subsection "An abstract, simplistic machine"
-
-text {* There are only three instructions: *}
-datatype instr = ASIN loc aexp | JMPF bexp nat | JMPB nat
-
-text {* We describe execution of programs in the machine by
-  an operational (small step) semantics:
-*}
-consts  stepa1 :: "instr list \<Rightarrow> ((state\<times>nat) \<times> (state\<times>nat))set"
-
-syntax
-  "_stepa1" :: "[instr list,state,nat,state,nat] \<Rightarrow> bool"
-               ("_ |- <_,_>/ -1-> <_,_>" [50,0,0,0,0] 50)
-  "_stepa" :: "[instr list,state,nat,state,nat] \<Rightarrow> bool"
-               ("_ |-/ <_,_>/ -*-> <_,_>" [50,0,0,0,0] 50)
-
-syntax (xsymbols)
-  "_stepa1" :: "[instr list,state,nat,state,nat] \<Rightarrow> bool"
-               ("_ \<turnstile> \<langle>_,_\<rangle>/ -1\<rightarrow> \<langle>_,_\<rangle>" [50,0,0,0,0] 50)
-  "_stepa" :: "[instr list,state,nat,state,nat] \<Rightarrow> bool"
-               ("_ \<turnstile>/ \<langle>_,_\<rangle>/ -*\<rightarrow> \<langle>_,_\<rangle>" [50,0,0,0,0] 50)
-
-translations  
-  "P \<turnstile> \<langle>s,m\<rangle> -1\<rightarrow> \<langle>t,n\<rangle>" == "((s,m),t,n) : stepa1 P"
-  "P \<turnstile> \<langle>s,m\<rangle> -*\<rightarrow> \<langle>t,n\<rangle>" == "((s,m),t,n) : ((stepa1 P)^*)"
-
-inductive "stepa1 P"
-intros
-ASIN[simp]:
-  "\<lbrakk> n<size P; P!n = ASIN x a \<rbrakk> \<Longrightarrow> P \<turnstile> \<langle>s,n\<rangle> -1\<rightarrow> \<langle>s[x\<mapsto> a s],Suc n\<rangle>"
-JMPFT[simp,intro]:
-  "\<lbrakk> n<size P; P!n = JMPF b i;  b s \<rbrakk> \<Longrightarrow> P \<turnstile> \<langle>s,n\<rangle> -1\<rightarrow> \<langle>s,Suc n\<rangle>"
-JMPFF[simp,intro]:
-  "\<lbrakk> n<size P; P!n = JMPF b i; ~b s; m=n+i \<rbrakk> \<Longrightarrow> P \<turnstile> \<langle>s,n\<rangle> -1\<rightarrow> \<langle>s,m\<rangle>"
-JMPB[simp]:
-  "\<lbrakk> n<size P; P!n = JMPB i; i <= n; j = n-i \<rbrakk> \<Longrightarrow> P \<turnstile> \<langle>s,n\<rangle> -1\<rightarrow> \<langle>s,j\<rangle>"
+theory Compiler = Machines:
 
 subsection "The compiler"
 
@@ -53,216 +14,287 @@
 "compile (x:==a) = [ASIN x a]"
 "compile (c1;c2) = compile c1 @ compile c2"
 "compile (\<IF> b \<THEN> c1 \<ELSE> c2) =
- [JMPF b (length(compile c1) + 2)] @ compile c1 @
- [JMPF (%x. False) (length(compile c2)+1)] @ compile c2"
-"compile (\<WHILE> b \<DO> c) = [JMPF b (length(compile c) + 2)] @ compile c @
+ [JMPF b (length(compile c1) + 1)] @ compile c1 @
+ [JMPF (%x. False) (length(compile c2))] @ compile c2"
+"compile (\<WHILE> b \<DO> c) = [JMPF b (length(compile c) + 1)] @ compile c @
  [JMPB (length(compile c)+1)]"
 
-declare nth_append[simp]
-
-subsection "Context lifting lemmas"
-
-text {* 
-  Some lemmas for lifting an execution into a prefix and suffix
-  of instructions; only needed for the first proof.
-*}
-lemma app_right_1:
-  "is1 \<turnstile> \<langle>s1,i1\<rangle> -1\<rightarrow> \<langle>s2,i2\<rangle> \<Longrightarrow> is1 @ is2 \<turnstile> \<langle>s1,i1\<rangle> -1\<rightarrow> \<langle>s2,i2\<rangle>"
-  (is "?P \<Longrightarrow> _")
-proof -
- assume ?P
- then show ?thesis
- by induct force+
-qed
-
-lemma app_left_1:
-  "is2 \<turnstile> \<langle>s1,i1\<rangle> -1\<rightarrow> \<langle>s2,i2\<rangle> \<Longrightarrow>
-   is1 @ is2 \<turnstile> \<langle>s1,size is1+i1\<rangle> -1\<rightarrow> \<langle>s2,size is1+i2\<rangle>"
-  (is "?P \<Longrightarrow> _")
-proof -
- assume ?P
- then show ?thesis
- by induct force+
-qed
-
-declare rtrancl_induct2 [induct set: rtrancl]
-
-lemma app_right:
-  "is1 \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s2,i2\<rangle> \<Longrightarrow> is1 @ is2 \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s2,i2\<rangle>"
-  (is "?P \<Longrightarrow> _")
-proof -
- assume ?P
- then show ?thesis
- proof induct
-   show "is1 @ is2 \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s1,i1\<rangle>" by simp
- next
-   fix s1' i1' s2 i2
-   assume "is1 @ is2 \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s1',i1'\<rangle>"
-          "is1 \<turnstile> \<langle>s1',i1'\<rangle> -1\<rightarrow> \<langle>s2,i2\<rangle>"
-   thus "is1 @ is2 \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s2,i2\<rangle>"
-     by(blast intro:app_right_1 rtrancl_trans)
- qed
-qed
-
-lemma app_left:
-  "is2 \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s2,i2\<rangle> \<Longrightarrow>
-   is1 @ is2 \<turnstile> \<langle>s1,size is1+i1\<rangle> -*\<rightarrow> \<langle>s2,size is1+i2\<rangle>"
-  (is "?P \<Longrightarrow> _")
-proof -
- assume ?P
- then show ?thesis
- proof induct
-   show "is1 @ is2 \<turnstile> \<langle>s1,length is1 + i1\<rangle> -*\<rightarrow> \<langle>s1,length is1 + i1\<rangle>" by simp
- next
-   fix s1' i1' s2 i2
-   assume "is1 @ is2 \<turnstile> \<langle>s1,length is1 + i1\<rangle> -*\<rightarrow> \<langle>s1',length is1 + i1'\<rangle>"
-          "is2 \<turnstile> \<langle>s1',i1'\<rangle> -1\<rightarrow> \<langle>s2,i2\<rangle>"
-   thus "is1 @ is2 \<turnstile> \<langle>s1,length is1 + i1\<rangle> -*\<rightarrow> \<langle>s2,length is1 + i2\<rangle>"
-     by(blast intro:app_left_1 rtrancl_trans)
- qed
-qed
-
-lemma app_left2:
-  "\<lbrakk> is2 \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s2,i2\<rangle>; j1 = size is1+i1; j2 = size is1+i2 \<rbrakk> \<Longrightarrow>
-   is1 @ is2 \<turnstile> \<langle>s1,j1\<rangle> -*\<rightarrow> \<langle>s2,j2\<rangle>"
-  by (simp add:app_left)
-
-lemma app1_left:
-  "is \<turnstile> \<langle>s1,i1\<rangle> -*\<rightarrow> \<langle>s2,i2\<rangle> \<Longrightarrow>
-   instr # is \<turnstile> \<langle>s1,Suc i1\<rangle> -*\<rightarrow> \<langle>s2,Suc i2\<rangle>"
-  by(erule app_left[of _ _ _ _ _ "[instr]",simplified])
-
 subsection "Compiler correctness"
 
-declare rtrancl_into_rtrancl[trans]
-        converse_rtrancl_into_rtrancl[trans]
-        rtrancl_trans[trans]
-
-text {*
-  The first proof; The statement is very intuitive,
-  but application of induction hypothesis requires the above lifting lemmas
-*}
-theorem "\<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t \<Longrightarrow> compile c \<turnstile> \<langle>s,0\<rangle> -*\<rightarrow> \<langle>t,length(compile c)\<rangle>"
-        (is "?P \<Longrightarrow> ?Q c s t")
+theorem assumes A: "\<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t"
+shows "\<And>p q. \<langle>compile c @ p,q,s\<rangle> -*\<rightarrow> \<langle>p,rev(compile c)@q,t\<rangle>"
+  (is "\<And>p q. ?P c s t p q")
 proof -
-  assume ?P
-  then show ?thesis
+  from A show "\<And>p q. ?thesis p q"
   proof induct
-    show "\<And>s. ?Q \<SKIP> s s" by simp
+    case Skip thus ?case by simp
   next
-    show "\<And>a s x. ?Q (x :== a) s (s[x\<mapsto> a s])" by force
+    case Assign thus ?case by force
+  next
+    case Semi thus ?case by simp (blast intro:rtrancl_trans)
   next
-    fix c0 c1 s0 s1 s2
-    assume "?Q c0 s0 s1"
-    hence "compile c0 @ compile c1 \<turnstile> \<langle>s0,0\<rangle> -*\<rightarrow> \<langle>s1,length(compile c0)\<rangle>"
-      by(rule app_right)
-    moreover assume "?Q c1 s1 s2"
-    hence "compile c0 @ compile c1 \<turnstile> \<langle>s1,length(compile c0)\<rangle> -*\<rightarrow>
-           \<langle>s2,length(compile c0)+length(compile c1)\<rangle>"
-    proof -
-      note app_left[of _ 0]
-      thus
-	      "\<And>is1 is2 s1 s2 i2.
-	      is2 \<turnstile> \<langle>s1,0\<rangle> -*\<rightarrow> \<langle>s2,i2\<rangle> \<Longrightarrow>
-	      is1 @ is2 \<turnstile> \<langle>s1,size is1\<rangle> -*\<rightarrow> \<langle>s2,size is1+i2\<rangle>"
-	      by simp
-    qed
-    ultimately have "compile c0 @ compile c1 \<turnstile> \<langle>s0,0\<rangle> -*\<rightarrow>
-                       \<langle>s2,length(compile c0)+length(compile c1)\<rangle>"
-      by (rule rtrancl_trans)
-    thus "?Q (c0; c1) s0 s2" by simp
+    fix b c0 c1 s0 s1 p q
+    assume IH: "\<And>p q. ?P c0 s0 s1 p q"
+    assume "b s0"
+    thus "?P (\<IF> b \<THEN> c0 \<ELSE> c1) s0 s1 p q"
+      by(simp add: IH[THEN rtrancl_trans])
+  next
+    case IfFalse thus ?case by(simp)
   next
-    fix b c0 c1 s0 s1
-    let ?comp = "compile(\<IF> b \<THEN> c0 \<ELSE> c1)"
-    assume "b s0" and IH: "?Q c0 s0 s1"
-    hence "?comp \<turnstile> \<langle>s0,0\<rangle> -1\<rightarrow> \<langle>s0,1\<rangle>" by auto
-    also from IH
-    have "?comp \<turnstile> \<langle>s0,1\<rangle> -*\<rightarrow> \<langle>s1,length(compile c0)+1\<rangle>"
-      by(auto intro:app1_left app_right)
-    also have "?comp \<turnstile> \<langle>s1,length(compile c0)+1\<rangle> -1\<rightarrow> \<langle>s1,length ?comp\<rangle>"
-      by(auto)
-    finally show "?Q (\<IF> b \<THEN> c0 \<ELSE> c1) s0 s1" .
+    case WhileFalse thus ?case by simp
   next
-    fix b c0 c1 s0 s1
-    let ?comp = "compile(\<IF> b \<THEN> c0 \<ELSE> c1)"
-    assume "\<not>b s0" and IH: "?Q c1 s0 s1"
-    hence "?comp \<turnstile> \<langle>s0,0\<rangle> -1\<rightarrow> \<langle>s0,length(compile c0) + 2\<rangle>" by auto
-    also from IH
-    have "?comp \<turnstile> \<langle>s0,length(compile c0)+2\<rangle> -*\<rightarrow> \<langle>s1,length ?comp\<rangle>"
-      by(force intro!:app_left2 app1_left)
-    finally show "?Q (\<IF> b \<THEN> c0 \<ELSE> c1) s0 s1" .
-  next
-    fix b c and s::state
-    assume "\<not>b s"
-    thus "?Q (\<WHILE> b \<DO> c) s s" by force
-  next
-    fix b c and s0::state and s1 s2
-    let ?comp = "compile(\<WHILE> b \<DO> c)"
-    assume "b s0" and
-      IHc: "?Q c s0 s1" and IHw: "?Q (\<WHILE> b \<DO> c) s1 s2"
-    hence "?comp \<turnstile> \<langle>s0,0\<rangle> -1\<rightarrow> \<langle>s0,1\<rangle>" by auto
-    also from IHc
-    have "?comp \<turnstile> \<langle>s0,1\<rangle> -*\<rightarrow> \<langle>s1,length(compile c)+1\<rangle>"
-      by(auto intro:app1_left app_right)
-    also have "?comp \<turnstile> \<langle>s1,length(compile c)+1\<rangle> -1\<rightarrow> \<langle>s1,0\<rangle>" by simp
-    also note IHw
-    finally show "?Q (\<WHILE> b \<DO> c) s0 s2".
+    fix b c and s0::state and s1 s2 p q
+    assume b: "b s0" and
+      IHc: "\<And>p q. ?P c s0 s1 p q" and
+      IHw: "\<And>p q. ?P (\<WHILE> b \<DO> c) s1 s2 p q"
+    show "?P (\<WHILE> b \<DO> c) s0 s2 p q"
+      using b  IHc[THEN rtrancl_trans] IHw by(simp)
   qed
 qed
 
-text {*
-  Second proof; statement is generalized to cater for prefixes and suffixes;
-  needs none of the lifting lemmas, but instantiations of pre/suffix.
-  *}
-theorem "\<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t \<Longrightarrow> 
-  !a z. a@compile c@z \<turnstile> \<langle>s,length a\<rangle> -*\<rightarrow> \<langle>t,length a + length(compile c)\<rangle>";
-apply(erule evalc.induct)
-      apply simp
-     apply(force intro!: ASIN)
-    apply(intro strip)
-    apply(erule_tac x = a in allE)
-    apply(erule_tac x = "a@compile c0" in allE)
-    apply(erule_tac x = "compile c1@z" in allE)
-    apply(erule_tac x = z in allE)
-    apply(simp add:add_assoc[THEN sym])
-    apply(blast intro:rtrancl_trans)
-(* \<IF> b \<THEN> c0 \<ELSE> c1; case b is true *)
-   apply(intro strip)
-   (* instantiate assumption sufficiently for later: *)
-   apply(erule_tac x = "a@[?I]" in allE)
-   apply(simp)
-   (* execute JMPF: *)
-   apply(rule converse_rtrancl_into_rtrancl)
-    apply(force intro!: JMPFT)
-   (* execute compile c0: *)
-   apply(rule rtrancl_trans)
-    apply(erule allE)
-    apply assumption
-   (* execute JMPF: *)
-   apply(rule r_into_rtrancl)
-   apply(force intro!: JMPFF)
-(* end of case b is true *)
-  apply(intro strip)
-  apply(erule_tac x = "a@[?I]@compile c0@[?J]" in allE)
-  apply(simp add:add_assoc)
-  apply(rule converse_rtrancl_into_rtrancl)
-   apply(force intro!: JMPFF)
-  apply(blast)
- apply(force intro: JMPFF)
-apply(intro strip)
-apply(erule_tac x = "a@[?I]" in allE)
-apply(erule_tac x = a in allE)
-apply(simp)
-apply(rule converse_rtrancl_into_rtrancl)
- apply(force intro!: JMPFT)
-apply(rule rtrancl_trans)
- apply(erule allE)
- apply assumption
-apply(rule converse_rtrancl_into_rtrancl)
- apply(force intro!: JMPB)
-apply(simp)
+text {* The other direction! *}
+
+inductive_cases [elim!]: "(([],p,s),next) : stepa1"
+
+lemma [simp]: "(\<langle>[],q,s\<rangle> -n\<rightarrow> \<langle>p',q',t\<rangle>) = (n=0 \<and> p' = [] \<and> q' = q \<and> t = s)"
+apply(rule iffI)
+ apply(erule converse_rel_powE, simp, fast)
+apply simp
+done
+
+lemma [simp]: "(\<langle>[],q,s\<rangle> -*\<rightarrow> \<langle>p',q',t\<rangle>) = (p' = [] \<and> q' = q \<and> t = s)"
+by(simp add: rtrancl_is_UN_rel_pow)
+
+constdefs
+ forws :: "instr \<Rightarrow> nat set"
+"forws instr == case instr of
+ ASIN x a \<Rightarrow> {0} |
+ JMPF b n \<Rightarrow> {0,n} |
+ JMPB n \<Rightarrow> {}"
+ backws :: "instr \<Rightarrow> nat set"
+"backws instr == case instr of
+ ASIN x a \<Rightarrow> {} |
+ JMPF b n \<Rightarrow> {} |
+ JMPB n \<Rightarrow> {n}"
+
+consts closed :: "nat \<Rightarrow> nat \<Rightarrow> instr list \<Rightarrow> bool"
+primrec
+"closed m n [] = True"
+"closed m n (instr#is) = ((\<forall>j \<in> forws instr. j \<le> size is+n) \<and>
+                        (\<forall>j \<in> backws instr. j \<le> m) \<and> closed (Suc m) n is)"
+
+lemma [simp]:
+ "\<And>m n. closed m n (C1@C2) =
+         (closed m (n+size C2) C1 \<and> closed (m+size C1) n C2)"
+by(induct C1, simp, simp add:plus_ac0)
+
+theorem [simp]: "\<And>m n. closed m n (compile c)"
+by(induct c, simp_all add:backws_def forws_def)
+
+lemma drop_lem: "n \<le> size(p1@p2)
+ \<Longrightarrow> (p1' @ p2 = drop n p1 @ drop (n - size p1) p2) =
+    (n \<le> size p1 & p1' = drop n p1)"
+apply(rule iffI)
+ defer apply simp
+apply(subgoal_tac "n \<le> size p1")
+ apply(rotate_tac -1)
+ apply simp
+apply(rule ccontr)
+apply(rotate_tac -1)
+apply(drule_tac f = length in arg_cong)
+apply simp
+apply arith
+done
+
+lemma reduce_exec1:
+ "\<langle>i # p1 @ p2,q1 @ q2,s\<rangle> -1\<rightarrow> \<langle>p1' @ p2,q1' @ q2,s'\<rangle> \<Longrightarrow>
+  \<langle>i # p1,q1,s\<rangle> -1\<rightarrow> \<langle>p1',q1',s'\<rangle>"
+by(clarsimp simp add: drop_lem split:instr.split_asm split_if_asm)
+
+
+lemma closed_exec1:
+ "\<lbrakk> closed 0 0 (rev q1 @ instr # p1);
+    \<langle>instr # p1 @ p2, q1 @ q2,r\<rangle> -1\<rightarrow> \<langle>p',q',r'\<rangle> \<rbrakk> \<Longrightarrow>
+  \<exists>p1' q1'. p' = p1'@p2 \<and> q' = q1'@q2 \<and> rev q1' @ p1' = rev q1 @ instr # p1"
+apply(clarsimp simp add:forws_def backws_def
+               split:instr.split_asm split_if_asm)
 done
 
-text {* Missing: the other direction! *}
+theorem closed_execn_decomp: "\<And>C1 C2 r.
+ \<lbrakk> closed 0 0 (rev C1 @ C2);
+   \<langle>C2 @ p1 @ p2, C1 @ q,r\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev C2 @ C1 @ q,t\<rangle> \<rbrakk>
+ \<Longrightarrow> \<exists>s n1 n2. \<langle>C2,C1,r\<rangle> -n1\<rightarrow> \<langle>[],rev C2 @ C1,s\<rangle> \<and>
+     \<langle>p1@p2,rev C2 @ C1 @ q,s\<rangle> -n2\<rightarrow> \<langle>p2, rev p1 @ rev C2 @ C1 @ q,t\<rangle> \<and>
+         n = n1+n2"
+(is "\<And>C1 C2 r. \<lbrakk>?CL C1 C2; ?H C1 C2 r n\<rbrakk> \<Longrightarrow> ?P C1 C2 r n")
+proof(induct n)
+  fix C1 C2 r
+  assume "?H C1 C2 r 0"
+  thus "?P C1 C2 r 0" by simp
+next
+  fix C1 C2 r n
+  assume IH: "\<And>C1 C2 r. ?CL C1 C2 \<Longrightarrow> ?H C1 C2 r n \<Longrightarrow> ?P C1 C2 r n"
+  assume CL: "?CL C1 C2" and H: "?H C1 C2 r (Suc n)"
+  show "?P C1 C2 r (Suc n)"
+  proof (cases C2)
+    assume "C2 = []" with H show ?thesis by simp
+  next
+    fix instr tlC2
+    assume C2: "C2 = instr # tlC2"
+    from H C2 obtain p' q' r'
+      where 1: "\<langle>instr # tlC2 @ p1 @ p2, C1 @ q,r\<rangle> -1\<rightarrow> \<langle>p',q',r'\<rangle>"
+      and n: "\<langle>p',q',r'\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev C2 @ C1 @ q,t\<rangle>"
+      by(fastsimp simp add:R_O_Rn_commute)
+    from CL closed_exec1[OF _ 1] C2
+    obtain C2' C1' where pq': "p' = C2' @ p1 @ p2 \<and> q' = C1' @ q"
+      and same: "rev C1' @ C2' = rev C1 @ C2"
+      by fastsimp
+    have rev_same: "rev C2' @ C1' = rev C2 @ C1"
+    proof -
+      have "rev C2' @ C1' = rev(rev C1' @ C2')" by simp
+      also have "\<dots> = rev(rev C1 @ C2)" by(simp only:same)
+      also have "\<dots> =  rev C2 @ C1" by simp
+      finally show ?thesis .
+    qed
+    hence rev_same': "\<And>p. rev C2' @ C1' @ p = rev C2 @ C1 @ p" by simp
+    from n have n': "\<langle>C2' @ p1 @ p2,C1' @ q,r'\<rangle> -n\<rightarrow>
+                     \<langle>p2,rev p1 @ rev C2' @ C1' @ q,t\<rangle>"
+      by(simp add:pq' rev_same')
+    from IH[OF _ n'] CL
+    obtain s n1 n2 where n1: "\<langle>C2',C1',r'\<rangle> -n1\<rightarrow> \<langle>[],rev C2 @ C1,s\<rangle>" and
+      "\<langle>p1 @ p2,rev C2 @ C1 @ q,s\<rangle> -n2\<rightarrow> \<langle>p2,rev p1 @ rev C2 @ C1 @ q,t\<rangle> \<and>
+       n = n1 + n2"
+      by(fastsimp simp add: same rev_same rev_same')
+    moreover
+    from 1 n1 pq' C2 have "\<langle>C2,C1,r\<rangle> -Suc n1\<rightarrow> \<langle>[],rev C2 @ C1,s\<rangle>"
+      by (simp del:relpow.simps exec_simp) (fast dest:reduce_exec1)
+    ultimately show ?thesis by (fastsimp simp del:relpow.simps)
+  qed
+qed
+
+lemma execn_decomp:
+"\<langle>compile c @ p1 @ p2,q,r\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev(compile c) @ q,t\<rangle>
+ \<Longrightarrow> \<exists>s n1 n2. \<langle>compile c,[],r\<rangle> -n1\<rightarrow> \<langle>[],rev(compile c),s\<rangle> \<and>
+     \<langle>p1@p2,rev(compile c) @ q,s\<rangle> -n2\<rightarrow> \<langle>p2, rev p1 @ rev(compile c) @ q,t\<rangle> \<and>
+         n = n1+n2"
+using closed_execn_decomp[of "[]",simplified] by simp
+
+lemma exec_star_decomp:
+"\<langle>compile c @ p1 @ p2,q,r\<rangle> -*\<rightarrow> \<langle>p2,rev p1 @ rev(compile c) @ q,t\<rangle>
+ \<Longrightarrow> \<exists>s. \<langle>compile c,[],r\<rangle> -*\<rightarrow> \<langle>[],rev(compile c),s\<rangle> \<and>
+     \<langle>p1@p2,rev(compile c) @ q,s\<rangle> -*\<rightarrow> \<langle>p2, rev p1 @ rev(compile c) @ q,t\<rangle>"
+by(simp add:rtrancl_is_UN_rel_pow)(fast dest: execn_decomp)
+
+
+(* Alternative:
+lemma exec_comp_n:
+"\<And>p1 p2 q r t n.
+ \<langle>compile c @ p1 @ p2,q,r\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev(compile c) @ q,t\<rangle>
+ \<Longrightarrow> \<exists>s n1 n2. \<langle>compile c,[],r\<rangle> -n1\<rightarrow> \<langle>[],rev(compile c),s\<rangle> \<and>
+     \<langle>p1@p2,rev(compile c) @ q,s\<rangle> -n2\<rightarrow> \<langle>p2, rev p1 @ rev(compile c) @ q,t\<rangle> \<and>
+         n = n1+n2"
+ (is "\<And>p1 p2 q r t n. ?H c p1 p2 q r t n \<Longrightarrow> ?P c p1 p2 q r t n")
+proof (induct c)
+*)
+
+text{*Warning: 
+@{prop"\<langle>compile c @ p,q,s\<rangle> -*\<rightarrow> \<langle>p,rev(compile c)@q,t\<rangle> \<Longrightarrow> \<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t"}
+is not true! *}
 
-end
+theorem "\<And>s t.
+ \<langle>compile c,[],s\<rangle> -*\<rightarrow> \<langle>[],rev(compile c),t\<rangle> \<Longrightarrow> \<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t"
+proof (induct c)
+  fix s t
+  assume "\<langle>compile SKIP,[],s\<rangle> -*\<rightarrow> \<langle>[],rev(compile SKIP),t\<rangle>"
+  thus "\<langle>SKIP,s\<rangle> \<longrightarrow>\<^sub>c t" by simp
+next
+  fix s t v f
+  assume "\<langle>compile(v :== f),[],s\<rangle> -*\<rightarrow> \<langle>[],rev(compile(v :== f)),t\<rangle>"
+  thus "\<langle>v :== f,s\<rangle> \<longrightarrow>\<^sub>c t" by simp
+next
+  fix s1 s3 c1 c2
+  let ?C1 = "compile c1" let ?C2 = "compile c2"
+  assume IH1: "\<And>s t. \<langle>?C1,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,t\<rangle> \<Longrightarrow> \<langle>c1,s\<rangle> \<longrightarrow>\<^sub>c t"
+     and IH2: "\<And>s t. \<langle>?C2,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,t\<rangle> \<Longrightarrow> \<langle>c2,s\<rangle> \<longrightarrow>\<^sub>c t"
+  assume "\<langle>compile(c1;c2),[],s1\<rangle> -*\<rightarrow> \<langle>[],rev(compile(c1;c2)),s3\<rangle>"
+  then obtain s2 where exec1: "\<langle>?C1,[],s1\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,s2\<rangle>" and
+             exec2: "\<langle>?C2,rev ?C1,s2\<rangle> -*\<rightarrow> \<langle>[],rev(compile(c1;c2)),s3\<rangle>"
+    by(fastsimp dest:exec_star_decomp[of _ _ "[]" "[]",simplified])
+  from exec2 have exec2': "\<langle>?C2,[],s2\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,s3\<rangle>"
+    using exec_star_decomp[of _ "[]" "[]"] by fastsimp
+  have "\<langle>c1,s1\<rangle> \<longrightarrow>\<^sub>c s2" using IH1 exec1 by simp
+  moreover have "\<langle>c2,s2\<rangle> \<longrightarrow>\<^sub>c s3" using IH2 exec2' by fastsimp
+  ultimately show "\<langle>c1;c2,s1\<rangle> \<longrightarrow>\<^sub>c s3" ..
+next
+  fix s t b c1 c2
+  let ?if = "IF b THEN c1 ELSE c2" let ?C = "compile ?if"
+  let ?C1 = "compile c1" let ?C2 = "compile c2"
+  assume IH1: "\<And>s t. \<langle>?C1,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,t\<rangle> \<Longrightarrow> \<langle>c1,s\<rangle> \<longrightarrow>\<^sub>c t"
+     and IH2: "\<And>s t. \<langle>?C2,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,t\<rangle> \<Longrightarrow> \<langle>c2,s\<rangle> \<longrightarrow>\<^sub>c t"
+     and H: "\<langle>?C,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C,t\<rangle>"
+  show "\<langle>?if,s\<rangle> \<longrightarrow>\<^sub>c t"
+  proof cases
+    assume b: "b s"
+    with H have "\<langle>?C1,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,t\<rangle>"
+      by (fastsimp dest:exec_star_decomp
+            [of _ "[JMPF (\<lambda>x. False) (size ?C2)]@?C2" "[]",simplified])
+    hence "\<langle>c1,s\<rangle> \<longrightarrow>\<^sub>c t" by(rule IH1)
+    with b show ?thesis ..
+  next
+    assume b: "\<not> b s"
+    with H have "\<langle>?C2,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,t\<rangle>"
+      using exec_star_decomp[of _ "[]" "[]"] by simp
+    hence "\<langle>c2,s\<rangle> \<longrightarrow>\<^sub>c t" by(rule IH2)
+    with b show ?thesis ..
+  qed
+next
+  fix b c s t
+  let ?w = "WHILE b DO c" let ?W = "compile ?w" let ?C = "compile c"
+  let ?j1 = "JMPF b (size ?C + 1)" let ?j2 = "JMPB (size ?C + 1)"
+  assume IHc: "\<And>s t. \<langle>?C,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C,t\<rangle> \<Longrightarrow> \<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t"
+     and H: "\<langle>?W,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
+  from H obtain k where ob:"\<langle>?W,[],s\<rangle> -k\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
+    by(simp add:rtrancl_is_UN_rel_pow) blast
+  { fix n have "\<And>s. \<langle>?W,[],s\<rangle> -n\<rightarrow> \<langle>[],rev ?W,t\<rangle> \<Longrightarrow> \<langle>?w,s\<rangle> \<longrightarrow>\<^sub>c t"
+    proof (induct n rule: less_induct)
+      fix n
+      assume IHm: "\<And>m s. \<lbrakk>m < n; \<langle>?W,[],s\<rangle> -m\<rightarrow> \<langle>[],rev ?W,t\<rangle> \<rbrakk> \<Longrightarrow> \<langle>?w,s\<rangle> \<longrightarrow>\<^sub>c t"
+      fix s
+      assume H: "\<langle>?W,[],s\<rangle> -n\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
+      show "\<langle>?w,s\<rangle> \<longrightarrow>\<^sub>c t"
+      proof cases
+	assume b: "b s"
+	then obtain m where m: "n = Suc m"
+          and 1: "\<langle>?C @ [?j2],[?j1],s\<rangle> -m\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
+	  using H by fastsimp
+	then obtain r n1 n2 where n1: "\<langle>?C,[],s\<rangle> -n1\<rightarrow> \<langle>[],rev ?C,r\<rangle>"
+          and n2: "\<langle>[?j2],rev ?C @ [?j1],r\<rangle> -n2\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
+          and n12: "m = n1+n2"
+	  using execn_decomp[of _ "[?j2]"]
+	  by(simp del: execn_simp) fast
+	have n2n: "n2 - 1 < n" using m n12 by arith
+	note b
+	moreover
+	{ from n1 have "\<langle>?C,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C,r\<rangle>"
+	    by (simp add:rtrancl_is_UN_rel_pow) fast
+	  hence "\<langle>c,s\<rangle> \<longrightarrow>\<^sub>c r" by(rule IHc)
+	}
+	moreover
+	{ have "n2 - 1 < n" using m n12 by arith
+	  moreover from n2 have "\<langle>?W,[],r\<rangle> -n2- 1\<rightarrow> \<langle>[],rev ?W,t\<rangle>" by fastsimp
+	  ultimately have "\<langle>?w,r\<rangle> \<longrightarrow>\<^sub>c t" by(rule IHm)
+	}
+	ultimately show ?thesis ..
+      next
+	assume b: "\<not> b s"
+	hence "t = s" using H by simp
+	with b show ?thesis by simp
+      qed
+    qed
+  }
+  with ob show "\<langle>?w,s\<rangle> \<longrightarrow>\<^sub>c t" by fast
+qed
+
+(* To Do: connect with Machine 0 using M_equiv *)
+
+end
\ No newline at end of file




