diff -r 0130ad32a612 -r 56f269baae76 src/HOL/IMP/Live_True.thy --- a/src/HOL/IMP/Live_True.thy Sun Nov 04 17:36:26 2012 +0100 +++ b/src/HOL/IMP/Live_True.thy Sun Nov 04 18:38:18 2012 +0100 @@ -90,6 +90,7 @@ with `bval b t1` `(c, t1) \ t2` show ?case by auto qed +subsection "Executability" instantiation com :: vars begin @@ -123,14 +124,27 @@ lemma cfinite[simp]: "finite(vars(c::com))" by (induction c) auto -text{* For code generation: *} +text{* Some code generation magic: executing @{const lfp} *} + +(* FIXME mv into Library *) +lemma lfp_while: + assumes "mono f" and "!!X. X \ C \ f X \ C" and "finite C" + shows "lfp f = while (\A. f A \ A) f {}" +unfolding while_def using assms by (rule lfp_the_while_option) blast + +text{* Make @{const L} executable by replacing @{const lfp} with the @{const +while} combinator from theory @{theory While_Combinator}. The @{const while} +combinator obeys the recursion equation +@{thm[display] While_Combinator.while_unfold[no_vars]} +and is thus executable. *} + lemma L_While: fixes b c X assumes "finite X" defines "f == \A. vars b \ X \ L c A" -shows "L (WHILE b DO c) X = the(while_option (\A. f A \ A) f {})" (is "_ = ?r") +shows "L (WHILE b DO c) X = while (\A. f A \ A) f {}" (is "_ = ?r") proof - let ?V = "vars b \ vars c \ X" have "lfp f = ?r" - proof(rule lfp_the_while_option[where C = "?V"]) + proof(rule lfp_while[where C = "?V"]) show "mono f" by(simp add: f_def mono_union_L) next fix Y show "Y \ ?V \ f Y \ ?V" @@ -141,30 +155,59 @@ thus ?thesis by (simp add: f_def) qed -text{* An approximate computation of the WHILE-case: *} +lemma L_While_set: "L (WHILE b DO c) (set xs) = + (let f = (\A. vars b \ set xs \ L c A) + in while (\A. f A \ A) f {})" +by(simp add: L_While del: L.simps(5)) + +text{* Replace the equation for L WHILE by the executable @{thm[source] L_While_set}: *} +lemmas [code] = L.simps(1-4) L_While_set +text{* Sorry, this syntax is odd. *} -fun iter :: "('a \ 'a) \ nat \ 'a \ 'a \ 'a" -where +lemma "(let b = Less (N 0) (V ''y''); c = ''y'' ::= V ''x''; ''x'' ::= V ''z'' + in L (WHILE b DO c) {''y''}) = {''x'', ''y'', ''z''}" +by eval + + +subsection "Approximating WHILE" + +text{* The final parameter is the default value: *} + +fun iter :: "('a \ 'a) \ nat \ 'a \ 'a \ 'a" where "iter f 0 p d = d" | "iter f (Suc n) p d = (if f p = p then p else iter f n (f p) d)" -lemma iter_pfp: - "f d \ d \ mono f \ x \ f x \ f(iter f i x d) \ iter f i x d" -apply(induction i arbitrary: x) - apply simp -apply (simp add: mono_def) -done +text{* A version of @{const L} with a bounded number of iterations (here: 2) +in the WHILE case: *} -lemma iter_While_pfp: -fixes b c X W k f -defines "f == \A. vars b \ X \ L c A" and "W == vars b \ vars c \ X" -and "P == iter f k {} W" -shows "f P \ P" -proof- - have "f W \ W" unfolding f_def W_def using L_subset_vars[of c] by blast - have "mono f" by(simp add: f_def mono_union_L) - from iter_pfp[of f, OF `f W \ W` `mono f` empty_subsetI] - show ?thesis by(simp add: P_def) +fun Lb :: "com \ vname set \ vname set" where +"Lb SKIP X = X" | +"Lb (x ::= a) X = (if x:X then X-{x} \ vars a else X)" | +"Lb (c\<^isub>1; c\<^isub>2) X = (Lb c\<^isub>1 \ Lb c\<^isub>2) X" | +"Lb (IF b THEN c\<^isub>1 ELSE c\<^isub>2) X = vars b \ Lb c\<^isub>1 X \ Lb c\<^isub>2 X" | +"Lb (WHILE b DO c) X = iter (\A. vars b \ X \ Lb c A) 2 {} (vars b \ vars c \ X)" + +lemma lfp_subset_iter: + "\ mono f; !!X. f X \ f' X; lfp f \ D \ \ lfp f \ iter f' n A D" +proof(induction n arbitrary: A) + case 0 thus ?case by simp +next + case Suc thus ?case by simp (metis lfp_lowerbound) qed +lemma "L c X \ Lb c X" +proof(induction c arbitrary: X) + case (While b c) + let ?f = "\A. vars b \ X \ L c A" + let ?fb = "\A. vars b \ X \ Lb c A" + show ?case + proof (simp, rule lfp_subset_iter[OF mono_union_L]) + show "!!X. ?f X \ ?fb X" using While.IH by blast + show "lfp ?f \ vars b \ vars c \ X" + by (metis (full_types) L.simps(5) L_subset_vars vars_com.simps(5)) + qed +next + case Seq thus ?case by simp (metis (full_types) L_mono monoD subset_trans) +qed auto + end