src/HOL/IMP/Compiler.thy
changeset 52915 c10bd1f49ff5
parent 52906 ba514b5aa809
child 52924 9587134ec780
equal deleted inserted replaced
52914:7a1537b54f16 52915:c10bd1f49ff5
     1 (* Author: Tobias Nipkow and Gerwin Klein *)
     1 (* Author: Tobias Nipkow and Gerwin Klein *)
     2 
     2 
     3 header "Compiler for IMP"
     3 header "Compiler for IMP"
     4 
     4 
     5 theory Compiler imports Big_Step 
     5 theory Compiler imports Big_Step Star
     6 begin
     6 begin
     7 
     7 
     8 subsection "List setup"
     8 subsection "List setup"
     9 
     9 
    10 text {* 
    10 text {* 
    61      ("(_/ \<turnstile> (_ \<rightarrow>/ _))" [59,0,59] 60) 
    61      ("(_/ \<turnstile> (_ \<rightarrow>/ _))" [59,0,59] 60) 
    62 where
    62 where
    63   "P \<turnstile> c \<rightarrow> c' = 
    63   "P \<turnstile> c \<rightarrow> c' = 
    64   (\<exists>i s stk. c = (i,s,stk) \<and> c' = iexec(P!!i) (i,s,stk) \<and> 0 \<le> i \<and> i < size P)"
    64   (\<exists>i s stk. c = (i,s,stk) \<and> c' = iexec(P!!i) (i,s,stk) \<and> 0 \<le> i \<and> i < size P)"
    65 
    65 
       
    66 (*
    66 declare exec1_def [simp]
    67 declare exec1_def [simp]
       
    68 *)
    67 
    69 
    68 lemma exec1I [intro, code_pred_intro]:
    70 lemma exec1I [intro, code_pred_intro]:
    69   "c' = iexec (P!!i) (i,s,stk) \<Longrightarrow> 0 \<le> i \<Longrightarrow> i < size P
    71   "c' = iexec (P!!i) (i,s,stk) \<Longrightarrow> 0 \<le> i \<Longrightarrow> i < size P
    70   \<Longrightarrow> P \<turnstile> (i,s,stk) \<rightarrow> c'"
    72   \<Longrightarrow> P \<turnstile> (i,s,stk) \<rightarrow> c'"
    71 by simp
    73 by (simp add: exec1_def)
    72 
    74 
    73 inductive exec :: "instr list \<Rightarrow> config \<Rightarrow> config \<Rightarrow> bool"
    75 abbreviation 
    74    ("(_/ \<turnstile> (_ \<rightarrow>*/ _))" 50)
    76   exec :: "instr list \<Rightarrow> config \<Rightarrow> config \<Rightarrow> bool" ("(_/ \<turnstile> (_ \<rightarrow>*/ _))" 50)
    75 where
    77 where
    76 refl: "P \<turnstile> c \<rightarrow>* c" |
    78   "exec P \<equiv> star (exec1 P)"
    77 step: "P \<turnstile> c \<rightarrow> c' \<Longrightarrow> P \<turnstile> c' \<rightarrow>* c'' \<Longrightarrow> P \<turnstile> c \<rightarrow>* c''"
    79 
    78 
    80 declare star.step[intro]
    79 declare refl[intro] step[intro]
    81 
    80 
    82 lemmas exec_induct = star.induct [of "exec1 P", split_format(complete)]
    81 lemmas exec_induct = exec.induct[split_format(complete)]
    83 
    82 
    84 code_pred exec1 by (metis exec1_def)
    83 code_pred exec by fastforce
       
    84 
    85 
    85 values
    86 values
    86   "{(i,map t [''x'',''y''],stk) | i t stk.
    87   "{(i,map t [''x'',''y''],stk) | i t stk.
    87     [LOAD ''y'', STORE ''x''] \<turnstile>
    88     [LOAD ''y'', STORE ''x''] \<turnstile>
    88     (0, <''x'' := 3, ''y'' := 4>, []) \<rightarrow>* (i,t,stk)}"
    89     (0, <''x'' := 3, ''y'' := 4>, []) \<rightarrow>* (i,t,stk)}"
    89 
    90 
    90 
    91 
    91 subsection{* Verification infrastructure *}
    92 subsection{* Verification infrastructure *}
    92 
    93 
    93 lemma exec_trans: "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> P \<turnstile> c' \<rightarrow>* c'' \<Longrightarrow> P \<turnstile> c \<rightarrow>* c''"
       
    94 by (induction rule: exec.induct) fastforce+
       
    95 
       
    96 text{* Below we need to argue about the execution of code that is embedded in
    94 text{* Below we need to argue about the execution of code that is embedded in
    97 larger programs. For this purpose we show that execution is preserved by
    95 larger programs. For this purpose we show that execution is preserved by
    98 appending code to the left or right of a program. *}
    96 appending code to the left or right of a program. *}
    99 
    97 
   100 lemma iexec_shift [simp]: 
    98 lemma iexec_shift [simp]: 
   101   "((n+i',s',stk') = iexec x (n+i,s,stk)) = ((i',s',stk') = iexec x (i,s,stk))"
    99   "((n+i',s',stk') = iexec x (n+i,s,stk)) = ((i',s',stk') = iexec x (i,s,stk))"
   102 by(auto split:instr.split)
   100 by(auto split:instr.split)
   103 
   101 
   104 lemma exec1_appendR: "P \<turnstile> c \<rightarrow> c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow> c'"
   102 lemma exec1_appendR: "P \<turnstile> c \<rightarrow> c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow> c'"
   105 by auto
   103 by (auto simp: exec1_def)
   106 
   104 
   107 lemma exec_appendR: "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow>* c'"
   105 lemma exec_appendR: "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow>* c'"
   108 by (induction rule: exec.induct) (fastforce intro: exec1_appendR)+
   106 by (induction rule: star.induct) (fastforce intro: exec1_appendR)+
   109 
   107 
   110 lemma exec1_appendL:
   108 lemma exec1_appendL:
   111   fixes i i' :: int 
   109   fixes i i' :: int 
   112   shows
   110   shows
   113   "P \<turnstile> (i,s,stk) \<rightarrow> (i',s',stk') \<Longrightarrow>
   111   "P \<turnstile> (i,s,stk) \<rightarrow> (i',s',stk') \<Longrightarrow>
   114    P' @ P \<turnstile> (size(P')+i,s,stk) \<rightarrow> (size(P')+i',s',stk')"
   112    P' @ P \<turnstile> (size(P')+i,s,stk) \<rightarrow> (size(P')+i',s',stk')"
       
   113   unfolding exec1_def
   115   by (auto split: instr.split)
   114   by (auto split: instr.split)
   116 
   115 
   117 lemma exec_appendL:
   116 lemma exec_appendL:
   118   fixes i i' :: int 
   117   fixes i i' :: int 
   119   shows
   118   shows
   152  size P \<le> i' \<Longrightarrow>
   151  size P \<le> i' \<Longrightarrow>
   153  P' \<turnstile>  (i' - size P,s',stk') \<rightarrow>* (i'',s'',stk'') \<Longrightarrow>
   152  P' \<turnstile>  (i' - size P,s',stk') \<rightarrow>* (i'',s'',stk'') \<Longrightarrow>
   154  j'' = size P + i''
   153  j'' = size P + i''
   155  \<Longrightarrow>
   154  \<Longrightarrow>
   156  P @ P' \<turnstile> (0,s,stk) \<rightarrow>* (j'',s'',stk'')"
   155  P @ P' \<turnstile> (0,s,stk) \<rightarrow>* (j'',s'',stk'')"
   157 by(metis exec_trans[OF exec_appendR exec_appendL_if])
   156 by(metis star_trans[OF exec_appendR exec_appendL_if])
   158 
   157 
   159 
   158 
   160 declare Let_def[simp]
   159 declare Let_def[simp]
   161 
   160 
   162 
   161 
   235   have "?cc1 @ ?cc2 \<turnstile> (0,s1,stk) \<rightarrow>* (size ?cc1,s2,stk)"
   234   have "?cc1 @ ?cc2 \<turnstile> (0,s1,stk) \<rightarrow>* (size ?cc1,s2,stk)"
   236     using Seq.IH(1) by fastforce
   235     using Seq.IH(1) by fastforce
   237   moreover
   236   moreover
   238   have "?cc1 @ ?cc2 \<turnstile> (size ?cc1,s2,stk) \<rightarrow>* (size(?cc1 @ ?cc2),s3,stk)"
   237   have "?cc1 @ ?cc2 \<turnstile> (size ?cc1,s2,stk) \<rightarrow>* (size(?cc1 @ ?cc2),s3,stk)"
   239     using Seq.IH(2) by fastforce
   238     using Seq.IH(2) by fastforce
   240   ultimately show ?case by simp (blast intro: exec_trans)
   239   ultimately show ?case by simp (blast intro: star_trans)
   241 next
   240 next
   242   case (WhileTrue b s1 c s2 s3)
   241   case (WhileTrue b s1 c s2 s3)
   243   let ?cc = "ccomp c"
   242   let ?cc = "ccomp c"
   244   let ?cb = "bcomp b False (size ?cc + 1)"
   243   let ?cb = "bcomp b False (size ?cc + 1)"
   245   let ?cw = "ccomp(WHILE b DO c)"
   244   let ?cw = "ccomp(WHILE b DO c)"
   251   moreover
   250   moreover
   252   have "?cw \<turnstile> (size ?cb + size ?cc,s2,stk) \<rightarrow>* (0,s2,stk)"
   251   have "?cw \<turnstile> (size ?cb + size ?cc,s2,stk) \<rightarrow>* (0,s2,stk)"
   253     by fastforce
   252     by fastforce
   254   moreover
   253   moreover
   255   have "?cw \<turnstile> (0,s2,stk) \<rightarrow>* (size ?cw,s3,stk)" by(rule WhileTrue.IH(2))
   254   have "?cw \<turnstile> (0,s2,stk) \<rightarrow>* (size ?cw,s3,stk)" by(rule WhileTrue.IH(2))
   256   ultimately show ?case by(blast intro: exec_trans)
   255   ultimately show ?case by(blast intro: star_trans)
   257 qed fastforce+
   256 qed fastforce+
   258 
   257 
   259 end
   258 end