header {* \isaheader{Partial Function Package Setup} *}
theory Refine_Pfun
imports Refine_Basic Refine_Det
begin
text {*
In this theory, we set up the partial function package to be used
with our refinement framework.
*}
subsection {* Nondeterministic Result Monad *}
interpretation nrec!:
partial_function_definitions "op ≤" "Sup::'a nres set => 'a nres"
by unfold_locales (auto simp add: Sup_upper Sup_least)
print_theorems
lemma nrec_admissible: "nrec.admissible (λ(f::'a => 'b nres).
(∀x0. f x0 ≤ SPEC (P x0)))"
apply (rule ccpo.admissibleI)
apply (unfold fun_lub_def)
apply (intro allI impI)
apply (rule Sup_least)
apply auto
done
declaration {* Partial_Function.init "nrec" @{term nrec.fixp_fun}
@{term nrec.mono_body} @{thm nrec.fixp_rule_uc} @{thm nrec.fixp_induct_uc}
(*SOME @{thm fixp_induct_nrec}*) (NONE) *}
lemma bind_mono_pfun[partial_function_mono]:
fixes C :: "'a => ('b => 'c nres) => ('d nres)"
shows
"[| monotone (fun_ord op ≤) op ≤ B;
!!y. monotone (fun_ord op ≤) op ≤ (λf. C y f) |] ==>
monotone (fun_ord op ≤) op ≤ (λf. bind (B f) (λy. C y f))"
apply rule
apply (rule Refine_Basic.bind_mono)
apply (blast dest: monotoneD)+
done
subsection {* Deterministic Result Monad *}
interpretation drec!:
partial_function_definitions "op ≤" "Sup::'a dres set => 'a dres"
by unfold_locales (auto simp add: Sup_upper Sup_least)
lemma drec_admissible: "drec.admissible (λ(f::'a => 'b dres).
(∀x. P x -->
(f x ≠ dFAIL ∧
(∀r. f x = dRETURN r --> Q x r))))"
proof -
have [simp]: "fun_ord (op ≤::'b dres => _ => _) = op ≤"
apply (intro ext)
unfolding fun_ord_def le_fun_def
by (rule refl)
have [simp]: "!!A x. {y. ∃f∈A. y = f x} = (λf. f x)`A" by auto
show ?thesis
apply (rule ccpo.admissibleI)
apply (unfold fun_lub_def)
apply clarsimp
apply (drule_tac x=x in point_chainI)
apply (erule dres_Sup_chain_cases)
apply (simp only: SUP_def)
apply simp
apply (simp only: SUP_def)
apply auto []
apply (simp only: SUP_def)
apply force
done
qed
declaration {* Partial_Function.init "drec" @{term drec.fixp_fun}
@{term drec.mono_body} @{thm drec.fixp_rule_uc} @{thm drec.fixp_induct_uc}
NONE *}
lemma drec_bind_mono_pfun[partial_function_mono]:
fixes C :: "'a => ('b => 'c dres) => ('d dres)"
shows
"[| monotone (fun_ord op ≤) op ≤ B;
!!y. monotone (fun_ord op ≤) op ≤ (λf. C y f) |] ==>
monotone (fun_ord op ≤) op ≤ (λf. dbind (B f) (λy. C y f))"
apply rule
apply (rule dbind_mono)
apply (blast dest: monotoneD)+
done
end