246 |
246 |
247 abbreviation "tailrec_ord \<equiv> flat_ord undefined" |
247 abbreviation "tailrec_ord \<equiv> flat_ord undefined" |
248 abbreviation "mono_tailrec \<equiv> monotone (fun_ord tailrec_ord) tailrec_ord" |
248 abbreviation "mono_tailrec \<equiv> monotone (fun_ord tailrec_ord) tailrec_ord" |
249 |
249 |
250 lemma tailrec_admissible: |
250 lemma tailrec_admissible: |
251 "ccpo.admissible (fun_lub (flat_lub undefined)) (fun_ord tailrec_ord) |
251 "ccpo.admissible (fun_lub (flat_lub c)) (fun_ord (flat_ord c)) |
252 (\<lambda>a. \<forall>x. a x \<noteq> undefined \<longrightarrow> P x (a x))" |
252 (\<lambda>a. \<forall>x. a x \<noteq> c \<longrightarrow> P x (a x))" |
253 proof(intro ccpo.admissibleI strip) |
253 proof(intro ccpo.admissibleI strip) |
254 fix A x |
254 fix A x |
255 assume chain: "Complete_Partial_Order.chain (fun_ord tailrec_ord) A" |
255 assume chain: "Complete_Partial_Order.chain (fun_ord (flat_ord c)) A" |
256 and P [rule_format]: "\<forall>f\<in>A. \<forall>x. f x \<noteq> undefined \<longrightarrow> P x (f x)" |
256 and P [rule_format]: "\<forall>f\<in>A. \<forall>x. f x \<noteq> c \<longrightarrow> P x (f x)" |
257 and defined: "fun_lub (flat_lub undefined) A x \<noteq> undefined" |
257 and defined: "fun_lub (flat_lub c) A x \<noteq> c" |
258 from defined obtain f where f: "f \<in> A" "f x \<noteq> undefined" |
258 from defined obtain f where f: "f \<in> A" "f x \<noteq> c" |
259 by(auto simp add: fun_lub_def flat_lub_def split: split_if_asm) |
259 by(auto simp add: fun_lub_def flat_lub_def split: split_if_asm) |
260 hence "P x (f x)" by(rule P) |
260 hence "P x (f x)" by(rule P) |
261 moreover from chain f have "\<forall>f' \<in> A. f' x = undefined \<or> f' x = f x" |
261 moreover from chain f have "\<forall>f' \<in> A. f' x = c \<or> f' x = f x" |
262 by(auto 4 4 simp add: Complete_Partial_Order.chain_def flat_ord_def fun_ord_def) |
262 by(auto 4 4 simp add: Complete_Partial_Order.chain_def flat_ord_def fun_ord_def) |
263 hence "fun_lub (flat_lub undefined) A x = f x" |
263 hence "fun_lub (flat_lub c) A x = f x" |
264 using f by(auto simp add: fun_lub_def flat_lub_def) |
264 using f by(auto simp add: fun_lub_def flat_lub_def) |
265 ultimately show "P x (fun_lub (flat_lub undefined) A x)" by simp |
265 ultimately show "P x (fun_lub (flat_lub c) A x)" by simp |
266 qed |
266 qed |
267 |
267 |
268 lemma fixp_induct_tailrec: |
268 lemma fixp_induct_tailrec: |
269 fixes F :: "'c \<Rightarrow> 'c" and |
269 fixes F :: "'c \<Rightarrow> 'c" and |
270 U :: "'c \<Rightarrow> 'b \<Rightarrow> 'a" and |
270 U :: "'c \<Rightarrow> 'b \<Rightarrow> 'a" and |
271 C :: "('b \<Rightarrow> 'a) \<Rightarrow> 'c" and |
271 C :: "('b \<Rightarrow> 'a) \<Rightarrow> 'c" and |
272 P :: "'b \<Rightarrow> 'a \<Rightarrow> bool" and |
272 P :: "'b \<Rightarrow> 'a \<Rightarrow> bool" and |
273 x :: "'b" |
273 x :: "'b" |
274 assumes mono: "\<And>x. mono_tailrec (\<lambda>f. U (F (C f)) x)" |
274 assumes mono: "\<And>x. monotone (fun_ord (flat_ord c)) (flat_ord c) (\<lambda>f. U (F (C f)) x)" |
275 assumes eq: "f \<equiv> C (ccpo.fixp (fun_lub (flat_lub undefined)) (fun_ord tailrec_ord) (\<lambda>f. U (F (C f))))" |
275 assumes eq: "f \<equiv> C (ccpo.fixp (fun_lub (flat_lub c)) (fun_ord (flat_ord c)) (\<lambda>f. U (F (C f))))" |
276 assumes inverse2: "\<And>f. U (C f) = f" |
276 assumes inverse2: "\<And>f. U (C f) = f" |
277 assumes step: "\<And>f x y. (\<And>x y. U f x = y \<Longrightarrow> y \<noteq> undefined \<Longrightarrow> P x y) \<Longrightarrow> U (F f) x = y \<Longrightarrow> y \<noteq> undefined \<Longrightarrow> P x y" |
277 assumes step: "\<And>f x y. (\<And>x y. U f x = y \<Longrightarrow> y \<noteq> c \<Longrightarrow> P x y) \<Longrightarrow> U (F f) x = y \<Longrightarrow> y \<noteq> c \<Longrightarrow> P x y" |
278 assumes result: "U f x = y" |
278 assumes result: "U f x = y" |
279 assumes defined: "y \<noteq> undefined" |
279 assumes defined: "y \<noteq> c" |
280 shows "P x y" |
280 shows "P x y" |
281 proof - |
281 proof - |
282 have "\<forall>x y. U f x = y \<longrightarrow> y \<noteq> undefined \<longrightarrow> P x y" |
282 have "\<forall>x y. U f x = y \<longrightarrow> y \<noteq> c \<longrightarrow> P x y" |
283 by(rule tailrec.fixp_induct_uc[of U F C, OF mono eq inverse2])(auto intro: step tailrec_admissible) |
283 by(rule partial_function_definitions.fixp_induct_uc[OF flat_interpretation, of _ U F C, OF mono eq inverse2]) |
|
284 (auto intro: step tailrec_admissible) |
284 thus ?thesis using result defined by blast |
285 thus ?thesis using result defined by blast |
285 qed |
286 qed |
286 |
287 |
287 lemma admissible_image: |
288 lemma admissible_image: |
288 assumes pfun: "partial_function_definitions le lub" |
289 assumes pfun: "partial_function_definitions le lub" |
389 using step defined option.fixp_induct_uc[of U F C, OF mono eq inverse2 option_admissible] |
390 using step defined option.fixp_induct_uc[of U F C, OF mono eq inverse2 option_admissible] |
390 by blast |
391 by blast |
391 |
392 |
392 declaration {* Partial_Function.init "tailrec" @{term tailrec.fixp_fun} |
393 declaration {* Partial_Function.init "tailrec" @{term tailrec.fixp_fun} |
393 @{term tailrec.mono_body} @{thm tailrec.fixp_rule_uc} @{thm tailrec.fixp_induct_uc} |
394 @{term tailrec.mono_body} @{thm tailrec.fixp_rule_uc} @{thm tailrec.fixp_induct_uc} |
394 (SOME @{thm fixp_induct_tailrec}) *} |
395 (SOME @{thm fixp_induct_tailrec[where c=undefined]}) *} |
395 |
396 |
396 declaration {* Partial_Function.init "option" @{term option.fixp_fun} |
397 declaration {* Partial_Function.init "option" @{term option.fixp_fun} |
397 @{term option.mono_body} @{thm option.fixp_rule_uc} @{thm option.fixp_induct_uc} |
398 @{term option.mono_body} @{thm option.fixp_rule_uc} @{thm option.fixp_induct_uc} |
398 (SOME @{thm fixp_induct_option}) *} |
399 (SOME @{thm fixp_induct_option}) *} |
399 |
400 |