src/HOL/Partial_Function.thy
changeset 53949 021a8ef97f5f
parent 53361 1cb7d3c0cf31
child 54630 9061af4d5ebc
equal deleted inserted replaced
53947:54b08afc03c7 53949:021a8ef97f5f
   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