header {* \isaheader{Transfer Setup} *}
theory Refine_Transfer
imports
Refine_Basic
Refine_While
Refine_Det
"Generic/RefineG_Transfer"
begin
subsection {* Transfer to Deterministic Result Lattice *}
text {*
TODO: Once lattice and ccpo are connected, also transfer to option monad, that
is a ccpo, but no complete lattice!
*}
subsubsection {* Connecting Deterministic and Non-Deterministic Result Lattices *}
definition "nres_of r ≡ case r of
dSUCCEEDi => SUCCEED
| dFAILi => FAIL
| dRETURN x => RETURN x"
lemma nres_of_simps[simp]:
"nres_of dSUCCEED = SUCCEED"
"nres_of dFAIL = FAIL"
"nres_of (dRETURN x) = RETURN x"
apply -
unfolding nres_of_def bot_dres_def top_dres_def
by (auto simp del: dres_internal_simps)
lemma nres_of_mono: "mono nres_of"
apply (rule)
apply (case_tac x, simp_all, case_tac y, simp_all)
done
lemma nres_transfer:
"nres_of dSUCCEED = SUCCEED"
"nres_of dFAIL = FAIL"
"nres_of a ≤ nres_of b <-> a≤b"
"nres_of a < nres_of b <-> a<b"
"is_chain A ==> nres_of (Sup A) = Sup (nres_of`A)"
"is_chain A ==> nres_of (Inf A) = Inf (nres_of`A)"
apply simp_all
apply (case_tac a, simp_all, case_tac [!] b, simp_all) [1]
apply (simp add: less_le)
apply (case_tac a, simp_all, case_tac [!] b, simp_all) [1]
apply (erule dres_Sup_chain_cases)
apply (cases "A={}")
apply auto []
apply (subgoal_tac "A={dSUCCEED}", auto) []
apply (case_tac "A={dRETURN r}")
apply auto []
apply (subgoal_tac "A={dSUCCEED,dRETURN r}", auto) []
apply (drule imageI[where f=nres_of])
apply auto []
apply (erule dres_Inf_chain_cases)
apply (cases "A={}")
apply auto []
apply (subgoal_tac "A={dFAIL}", auto) []
apply (case_tac "A={dRETURN r}")
apply auto []
apply (subgoal_tac "A={dFAIL,dRETURN r}", auto) []
apply (drule imageI[where f=nres_of])
apply (auto intro: bot_Inf [symmetric] simp add: INF_def simp del: Inf_image_eq) []
done
lemma nres_correctD:
assumes "nres_of S ≤ SPEC Φ"
shows
"S=dRETURN x ==> Φ x"
"S≠dFAIL"
using assms apply -
apply (cases S, simp_all)+
done
subsubsection {* Transfer Theorems Setup*}
interpretation dres!: dist_transfer nres_of
apply unfold_locales
apply (simp add: nres_transfer)
done
lemma det_FAIL[refine_transfer]: "nres_of (dFAIL) ≤ FAIL" by auto
lemma det_SUCCEED[refine_transfer]: "nres_of (dSUCCEED) ≤ SUCCEED" by auto
lemma det_SPEC: "Φ x ==> nres_of (dRETURN x) ≤ SPEC Φ" by simp
lemma det_RETURN[refine_transfer]:
"nres_of (dRETURN x) ≤ RETURN x" by simp
lemma det_bind[refine_transfer]:
assumes "nres_of m ≤ M"
assumes "!!x. nres_of (f x) ≤ F x"
shows "nres_of (dbind m f) ≤ bind M F"
using assms
apply (cases m)
apply (auto simp: pw_le_iff refine_pw_simps)
done
interpretation det_assert!: transfer_generic_Assert_remove
bind RETURN ASSERT ASSUME
nres_of
by unfold_locales
interpretation det_while!: transfer_WHILE
dbind dRETURN dWHILEIT dWHILEI dWHILET dWHILE
bind RETURN WHILEIT WHILEI WHILET WHILE nres_of
apply unfold_locales
apply (auto intro: det_bind)
done
subsection {* Transfer to Plain Function *}
interpretation plain!: transfer RETURN .
lemma plain_RETURN[refine_transfer]: "RETURN a ≤ RETURN a" by simp
lemma plain_bind[refine_transfer]:
"[|RETURN x ≤ M; !!x. RETURN (f x) ≤ F x|] ==> RETURN (Let x f) ≤ bind M F"
apply (erule order_trans[rotated,OF bind_mono(1)])
apply assumption
apply simp
done
interpretation plain_assert!: transfer_generic_Assert_remove
bind RETURN ASSERT ASSUME
RETURN
by unfold_locales
subsection {* Total correctness in deterministic monad *}
text {*
Sometimes one cannot extract total correct programs to executable plain
Isabelle functions, for example, if the total correctness only holds for
certain preconditions. In those cases, one can still show
@{text "RETURN (the_res S) ≤ S'"}. Here, @{text "the_res"} extracts
the result from a deterministic monad. As @{text "the_res"} is executable,
the above shows that @{text "(the_res S)"} is always a correct result.
*}
fun the_res where "the_res (dRETURN x) = x"
text {* The following lemma converts a proof-obligation
with result extraction to a transfer proof obligation,
and a proof obligation that the program yields not bottom.
Note that this rule has to be applied manually, as, otherwise,
it would interfere with the default setup, that tries to generate a
plain function.
*}
lemma the_resI:
assumes "nres_of S ≤ S'"
assumes "S ≠ dSUCCEED"
shows "RETURN (the_res S) ≤ S'"
using assms
by (cases S, simp_all)
text {* The following rule sets up a refinement goal, a transfer goal, and a
final optimization goal. *}
definition "detTAG x ≡ x"
lemma detTAGI: "x = detTAG x" unfolding detTAG_def by simp
lemma autoref_detI:
assumes "(b,a)∈〈R〉nres_rel"
assumes "RETURN c ≤ b"
assumes "c = detTAG d"
shows "(RETURN d, a)∈〈R〉nres_rel"
using assms
unfolding nres_rel_def detTAG_def
by simp
subsection {* Relator-Based Transfer *}
definition dres_nres_rel_internal_def:
"dres_nres_rel R ≡ {(c,a). nres_of c ≤ \<Down> R a}"
lemma dres_nres_rel_def: "〈R〉dres_nres_rel ≡ {(c,a). nres_of c ≤ \<Down> R a}"
by (simp add: dres_nres_rel_internal_def relAPP_def)
lemma dres_nres_relI[intro?]: "nres_of c ≤ \<Down> R a ==> (c,a)∈〈R〉dres_nres_rel"
by (simp add: dres_nres_rel_def)
lemma dres_nres_relD: "(c,a)∈〈R〉dres_nres_rel ==> nres_of c ≤ \<Down> R a"
by (simp add: dres_nres_rel_def)
lemma dres_nres_rel_as_br_conv:
"〈R〉dres_nres_rel = br nres_of (λ_. True) O 〈R〉nres_rel"
unfolding dres_nres_rel_def br_def nres_rel_def by auto
definition plain_nres_rel_internal_def:
"plain_nres_rel R ≡ {(c,a). RETURN c ≤ \<Down> R a}"
lemma plain_nres_rel_def: "〈R〉plain_nres_rel ≡ {(c,a). RETURN c ≤ \<Down> R a}"
by (simp add: plain_nres_rel_internal_def relAPP_def)
lemma plain_nres_relI[intro?]: "RETURN c ≤ \<Down> R a ==> (c,a)∈〈R〉plain_nres_rel"
by (simp add: plain_nres_rel_def)
lemma plain_nres_relD: "(c,a)∈〈R〉plain_nres_rel ==> RETURN c ≤ \<Down> R a"
by (simp add: plain_nres_rel_def)
lemma plain_nres_rel_as_br_conv:
"〈R〉plain_nres_rel = br RETURN (λ_. True) O 〈R〉nres_rel"
unfolding plain_nres_rel_def br_def nres_rel_def by auto
end