linear arithmetic splits certain operators (e.g. min, max, abs)
1 (* Title: HOL/IMP/Compiler.thy
3 Author: Tobias Nipkow, TUM
7 theory Compiler imports Machines begin
9 subsection "The compiler"
11 consts compile :: "com \<Rightarrow> instr list"
13 "compile \<SKIP> = []"
14 "compile (x:==a) = [SET x a]"
15 "compile (c1;c2) = compile c1 @ compile c2"
16 "compile (\<IF> b \<THEN> c1 \<ELSE> c2) =
17 [JMPF b (length(compile c1) + 1)] @ compile c1 @
18 [JMPF (\<lambda>x. False) (length(compile c2))] @ compile c2"
19 "compile (\<WHILE> b \<DO> c) = [JMPF b (length(compile c) + 1)] @ compile c @
20 [JMPB (length(compile c)+1)]"
22 subsection "Compiler correctness"
24 theorem assumes A: "\<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t"
25 shows "\<And>p q. \<langle>compile c @ p,q,s\<rangle> -*\<rightarrow> \<langle>p,rev(compile c)@q,t\<rangle>"
26 (is "\<And>p q. ?P c s t p q")
28 from A show "\<And>p q. ?thesis p q"
30 case Skip thus ?case by simp
32 case Assign thus ?case by force
34 case Semi thus ?case by simp (blast intro:rtrancl_trans)
37 assume IH: "\<And>p q. ?P c0 s0 s1 p q"
39 thus "?P (\<IF> b \<THEN> c0 \<ELSE> c1) s0 s1 p q"
40 by(simp add: IH[THEN rtrancl_trans])
42 case IfFalse thus ?case by(simp)
44 case WhileFalse thus ?case by simp
46 fix b c and s0::state and s1 s2 p q
48 IHc: "\<And>p q. ?P c s0 s1 p q" and
49 IHw: "\<And>p q. ?P (\<WHILE> b \<DO> c) s1 s2 p q"
50 show "?P (\<WHILE> b \<DO> c) s0 s2 p q"
51 using b IHc[THEN rtrancl_trans] IHw by(simp)
55 text {* The other direction! *}
57 inductive_cases [elim!]: "(([],p,s),next) : stepa1"
59 lemma [simp]: "(\<langle>[],q,s\<rangle> -n\<rightarrow> \<langle>p',q',t\<rangle>) = (n=0 \<and> p' = [] \<and> q' = q \<and> t = s)"
61 apply(erule converse_rel_powE, simp, fast)
65 lemma [simp]: "(\<langle>[],q,s\<rangle> -*\<rightarrow> \<langle>p',q',t\<rangle>) = (p' = [] \<and> q' = q \<and> t = s)"
66 by(simp add: rtrancl_is_UN_rel_pow)
69 forws :: "instr \<Rightarrow> nat set"
70 "forws instr == case instr of
71 SET x a \<Rightarrow> {0} |
72 JMPF b n \<Rightarrow> {0,n} |
73 JMPB n \<Rightarrow> {}"
74 backws :: "instr \<Rightarrow> nat set"
75 "backws instr == case instr of
76 SET x a \<Rightarrow> {} |
77 JMPF b n \<Rightarrow> {} |
78 JMPB n \<Rightarrow> {n}"
80 consts closed :: "nat \<Rightarrow> nat \<Rightarrow> instr list \<Rightarrow> bool"
82 "closed m n [] = True"
83 "closed m n (instr#is) = ((\<forall>j \<in> forws instr. j \<le> size is+n) \<and>
84 (\<forall>j \<in> backws instr. j \<le> m) \<and> closed (Suc m) n is)"
87 "\<And>m n. closed m n (C1@C2) =
88 (closed m (n+size C2) C1 \<and> closed (m+size C1) n C2)"
89 by(induct C1, simp, simp add:add_ac)
91 theorem [simp]: "\<And>m n. closed m n (compile c)"
92 by(induct c, simp_all add:backws_def forws_def)
94 lemma drop_lem: "n \<le> size(p1@p2)
95 \<Longrightarrow> (p1' @ p2 = drop n p1 @ drop (n - size p1) p2) =
96 (n \<le> size p1 & p1' = drop n p1)"
99 apply(subgoal_tac "n \<le> size p1")
102 apply(drule_tac f = length in arg_cong)
107 "\<langle>i # p1 @ p2,q1 @ q2,s\<rangle> -1\<rightarrow> \<langle>p1' @ p2,q1' @ q2,s'\<rangle> \<Longrightarrow>
108 \<langle>i # p1,q1,s\<rangle> -1\<rightarrow> \<langle>p1',q1',s'\<rangle>"
109 by(clarsimp simp add: drop_lem split:instr.split_asm split_if_asm)
113 "\<lbrakk> closed 0 0 (rev q1 @ instr # p1);
114 \<langle>instr # p1 @ p2, q1 @ q2,r\<rangle> -1\<rightarrow> \<langle>p',q',r'\<rangle> \<rbrakk> \<Longrightarrow>
115 \<exists>p1' q1'. p' = p1'@p2 \<and> q' = q1'@q2 \<and> rev q1' @ p1' = rev q1 @ instr # p1"
116 apply(clarsimp simp add:forws_def backws_def
117 split:instr.split_asm split_if_asm)
120 theorem closed_execn_decomp: "\<And>C1 C2 r.
121 \<lbrakk> closed 0 0 (rev C1 @ C2);
122 \<langle>C2 @ p1 @ p2, C1 @ q,r\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev C2 @ C1 @ q,t\<rangle> \<rbrakk>
123 \<Longrightarrow> \<exists>s n1 n2. \<langle>C2,C1,r\<rangle> -n1\<rightarrow> \<langle>[],rev C2 @ C1,s\<rangle> \<and>
124 \<langle>p1@p2,rev C2 @ C1 @ q,s\<rangle> -n2\<rightarrow> \<langle>p2, rev p1 @ rev C2 @ C1 @ q,t\<rangle> \<and>
126 (is "\<And>C1 C2 r. \<lbrakk>?CL C1 C2; ?H C1 C2 r n\<rbrakk> \<Longrightarrow> ?P C1 C2 r n")
129 assume "?H C1 C2 r 0"
130 thus "?P C1 C2 r 0" by simp
133 assume IH: "\<And>C1 C2 r. ?CL C1 C2 \<Longrightarrow> ?H C1 C2 r n \<Longrightarrow> ?P C1 C2 r n"
134 assume CL: "?CL C1 C2" and H: "?H C1 C2 r (Suc n)"
135 show "?P C1 C2 r (Suc n)"
137 assume "C2 = []" with H show ?thesis by simp
140 assume C2: "C2 = instr # tlC2"
141 from H C2 obtain p' q' r'
142 where 1: "\<langle>instr # tlC2 @ p1 @ p2, C1 @ q,r\<rangle> -1\<rightarrow> \<langle>p',q',r'\<rangle>"
143 and n: "\<langle>p',q',r'\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev C2 @ C1 @ q,t\<rangle>"
144 by(fastsimp simp add:R_O_Rn_commute)
145 from CL closed_exec1[OF _ 1] C2
146 obtain C2' C1' where pq': "p' = C2' @ p1 @ p2 \<and> q' = C1' @ q"
147 and same: "rev C1' @ C2' = rev C1 @ C2"
149 have rev_same: "rev C2' @ C1' = rev C2 @ C1"
151 have "rev C2' @ C1' = rev(rev C1' @ C2')" by simp
152 also have "\<dots> = rev(rev C1 @ C2)" by(simp only:same)
153 also have "\<dots> = rev C2 @ C1" by simp
154 finally show ?thesis .
156 hence rev_same': "\<And>p. rev C2' @ C1' @ p = rev C2 @ C1 @ p" by simp
157 from n have n': "\<langle>C2' @ p1 @ p2,C1' @ q,r'\<rangle> -n\<rightarrow>
158 \<langle>p2,rev p1 @ rev C2' @ C1' @ q,t\<rangle>"
159 by(simp add:pq' rev_same')
161 obtain s n1 n2 where n1: "\<langle>C2',C1',r'\<rangle> -n1\<rightarrow> \<langle>[],rev C2 @ C1,s\<rangle>" and
162 "\<langle>p1 @ p2,rev C2 @ C1 @ q,s\<rangle> -n2\<rightarrow> \<langle>p2,rev p1 @ rev C2 @ C1 @ q,t\<rangle> \<and>
164 by(fastsimp simp add: same rev_same rev_same')
166 from 1 n1 pq' C2 have "\<langle>C2,C1,r\<rangle> -Suc n1\<rightarrow> \<langle>[],rev C2 @ C1,s\<rangle>"
167 by (simp del:relpow.simps exec_simp) (fast dest:reduce_exec1)
168 ultimately show ?thesis by (fastsimp simp del:relpow.simps)
173 "\<langle>compile c @ p1 @ p2,q,r\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev(compile c) @ q,t\<rangle>
174 \<Longrightarrow> \<exists>s n1 n2. \<langle>compile c,[],r\<rangle> -n1\<rightarrow> \<langle>[],rev(compile c),s\<rangle> \<and>
175 \<langle>p1@p2,rev(compile c) @ q,s\<rangle> -n2\<rightarrow> \<langle>p2, rev p1 @ rev(compile c) @ q,t\<rangle> \<and>
177 using closed_execn_decomp[of "[]",simplified] by simp
179 lemma exec_star_decomp:
180 "\<langle>compile c @ p1 @ p2,q,r\<rangle> -*\<rightarrow> \<langle>p2,rev p1 @ rev(compile c) @ q,t\<rangle>
181 \<Longrightarrow> \<exists>s. \<langle>compile c,[],r\<rangle> -*\<rightarrow> \<langle>[],rev(compile c),s\<rangle> \<and>
182 \<langle>p1@p2,rev(compile c) @ q,s\<rangle> -*\<rightarrow> \<langle>p2, rev p1 @ rev(compile c) @ q,t\<rangle>"
183 by(simp add:rtrancl_is_UN_rel_pow)(fast dest: execn_decomp)
188 "\<And>p1 p2 q r t n.
189 \<langle>compile c @ p1 @ p2,q,r\<rangle> -n\<rightarrow> \<langle>p2,rev p1 @ rev(compile c) @ q,t\<rangle>
190 \<Longrightarrow> \<exists>s n1 n2. \<langle>compile c,[],r\<rangle> -n1\<rightarrow> \<langle>[],rev(compile c),s\<rangle> \<and>
191 \<langle>p1@p2,rev(compile c) @ q,s\<rangle> -n2\<rightarrow> \<langle>p2, rev p1 @ rev(compile c) @ q,t\<rangle> \<and>
193 (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")
198 @{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"}
202 \<langle>compile c,[],s\<rangle> -*\<rightarrow> \<langle>[],rev(compile c),t\<rangle> \<Longrightarrow> \<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t"
205 assume "\<langle>compile SKIP,[],s\<rangle> -*\<rightarrow> \<langle>[],rev(compile SKIP),t\<rangle>"
206 thus "\<langle>SKIP,s\<rangle> \<longrightarrow>\<^sub>c t" by simp
209 assume "\<langle>compile(v :== f),[],s\<rangle> -*\<rightarrow> \<langle>[],rev(compile(v :== f)),t\<rangle>"
210 thus "\<langle>v :== f,s\<rangle> \<longrightarrow>\<^sub>c t" by simp
213 let ?C1 = "compile c1" let ?C2 = "compile c2"
214 assume IH1: "\<And>s t. \<langle>?C1,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,t\<rangle> \<Longrightarrow> \<langle>c1,s\<rangle> \<longrightarrow>\<^sub>c t"
215 and IH2: "\<And>s t. \<langle>?C2,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,t\<rangle> \<Longrightarrow> \<langle>c2,s\<rangle> \<longrightarrow>\<^sub>c t"
216 assume "\<langle>compile(c1;c2),[],s1\<rangle> -*\<rightarrow> \<langle>[],rev(compile(c1;c2)),s3\<rangle>"
217 then obtain s2 where exec1: "\<langle>?C1,[],s1\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,s2\<rangle>" and
218 exec2: "\<langle>?C2,rev ?C1,s2\<rangle> -*\<rightarrow> \<langle>[],rev(compile(c1;c2)),s3\<rangle>"
219 by(fastsimp dest:exec_star_decomp[of _ _ "[]" "[]",simplified])
220 from exec2 have exec2': "\<langle>?C2,[],s2\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,s3\<rangle>"
221 using exec_star_decomp[of _ "[]" "[]"] by fastsimp
222 have "\<langle>c1,s1\<rangle> \<longrightarrow>\<^sub>c s2" using IH1 exec1 by simp
223 moreover have "\<langle>c2,s2\<rangle> \<longrightarrow>\<^sub>c s3" using IH2 exec2' by fastsimp
224 ultimately show "\<langle>c1;c2,s1\<rangle> \<longrightarrow>\<^sub>c s3" ..
227 let ?if = "IF b THEN c1 ELSE c2" let ?C = "compile ?if"
228 let ?C1 = "compile c1" let ?C2 = "compile c2"
229 assume IH1: "\<And>s t. \<langle>?C1,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,t\<rangle> \<Longrightarrow> \<langle>c1,s\<rangle> \<longrightarrow>\<^sub>c t"
230 and IH2: "\<And>s t. \<langle>?C2,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,t\<rangle> \<Longrightarrow> \<langle>c2,s\<rangle> \<longrightarrow>\<^sub>c t"
231 and H: "\<langle>?C,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C,t\<rangle>"
232 show "\<langle>?if,s\<rangle> \<longrightarrow>\<^sub>c t"
235 with H have "\<langle>?C1,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C1,t\<rangle>"
236 by (fastsimp dest:exec_star_decomp
237 [of _ "[JMPF (\<lambda>x. False) (size ?C2)]@?C2" "[]",simplified])
238 hence "\<langle>c1,s\<rangle> \<longrightarrow>\<^sub>c t" by(rule IH1)
239 with b show ?thesis ..
241 assume b: "\<not> b s"
242 with H have "\<langle>?C2,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C2,t\<rangle>"
243 using exec_star_decomp[of _ "[]" "[]"] by simp
244 hence "\<langle>c2,s\<rangle> \<longrightarrow>\<^sub>c t" by(rule IH2)
245 with b show ?thesis ..
249 let ?w = "WHILE b DO c" let ?W = "compile ?w" let ?C = "compile c"
250 let ?j1 = "JMPF b (size ?C + 1)" let ?j2 = "JMPB (size ?C + 1)"
251 assume IHc: "\<And>s t. \<langle>?C,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C,t\<rangle> \<Longrightarrow> \<langle>c,s\<rangle> \<longrightarrow>\<^sub>c t"
252 and H: "\<langle>?W,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
253 from H obtain k where ob:"\<langle>?W,[],s\<rangle> -k\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
254 by(simp add:rtrancl_is_UN_rel_pow) blast
255 { 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"
256 proof (induct n rule: less_induct)
258 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"
260 assume H: "\<langle>?W,[],s\<rangle> -n\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
261 show "\<langle>?w,s\<rangle> \<longrightarrow>\<^sub>c t"
264 then obtain m where m: "n = Suc m"
265 and "\<langle>?C @ [?j2],[?j1],s\<rangle> -m\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
267 then obtain r n1 n2 where n1: "\<langle>?C,[],s\<rangle> -n1\<rightarrow> \<langle>[],rev ?C,r\<rangle>"
268 and n2: "\<langle>[?j2],rev ?C @ [?j1],r\<rangle> -n2\<rightarrow> \<langle>[],rev ?W,t\<rangle>"
270 using execn_decomp[of _ "[?j2]"]
271 by(simp del: execn_simp) fast
272 have n2n: "n2 - 1 < n" using m n12 by arith
275 { from n1 have "\<langle>?C,[],s\<rangle> -*\<rightarrow> \<langle>[],rev ?C,r\<rangle>"
276 by (simp add:rtrancl_is_UN_rel_pow) fast
277 hence "\<langle>c,s\<rangle> \<longrightarrow>\<^sub>c r" by(rule IHc)
280 { have "n2 - 1 < n" using m n12 by arith
281 moreover from n2 have "\<langle>?W,[],r\<rangle> -n2- 1\<rightarrow> \<langle>[],rev ?W,t\<rangle>" by fastsimp
282 ultimately have "\<langle>?w,r\<rangle> \<longrightarrow>\<^sub>c t" by(rule IHm)
284 ultimately show ?thesis ..
286 assume b: "\<not> b s"
287 hence "t = s" using H by simp
288 with b show ?thesis by simp
292 with ob show "\<langle>?w,s\<rangle> \<longrightarrow>\<^sub>c t" by fast
295 (* TODO: connect with Machine 0 using M_equiv *)