Theory DataRefinement
theory DataRefinement
imports NREST
begin
subsection ‹Data Refinement›
lemma "{(1,2),(2,4)}``{1,2}={2,4}" by auto
definition conc_fun (‹⇓›) where
"conc_fun R m ≡ case m of FAILi ⇒ FAILT | REST X ⇒ REST (λc. Sup {X a| a. (c,a)∈R})"
definition abs_fun (‹⇑›) where
"abs_fun R m ≡ case m of FAILi ⇒ FAILT
| REST X ⇒ if dom X⊆Domain R then REST (λa. Sup {X c| c. (c,a)∈R}) else FAILT"
lemma
conc_fun_FAIL[simp]: "⇓R FAILT = FAILT" and
conc_fun_RES: "⇓R (REST X) = REST (λc. Sup {X a| a. (c,a)∈R})"
unfolding conc_fun_def by (auto split: nrest.split)
lemma nrest_Rel_mono: "A ≤ B ⟹ ⇓ R A ≤ ⇓ R B"
unfolding conc_fun_def by (fastforce split: nrest.split simp: le_fun_def intro!: Sup_mono)
subsubsection ‹Examples›
definition Rset where "Rset = { (c,a)| c a. set c = a}"
lemma "RETURNT [1,2,3] ≤ ⇓Rset (RETURNT {1,2,3})"
by (auto simp add: le_fun_def conc_fun_def RETURNT_def Rset_def)
lemma "RETURNT [1,2,3] ≤ ⇓Rset (RETURNT {1,2,3})"
by (auto simp add: le_fun_def conc_fun_def RETURNT_def Rset_def)
definition Reven where "Reven = { (c,a)| c a. even c = a}"
lemma "RETURNT 3 ≤ ⇓Reven (RETURNT False)"
by (auto simp add: le_fun_def conc_fun_def RETURNT_def Reven_def)
lemma "m ≤ ⇓Id m"
unfolding conc_fun_def RETURNT_def by (cases m) auto
lemma "m ≤ ⇓{} m ⟷ (m=FAILT ∨ m = SPECT bot)"
unfolding conc_fun_def RETURNT_def by (cases m) (auto simp add: bot.extremum_uniqueI le_fun_def)
lemma abs_fun_simps[simp]:
"⇑R FAILT = FAILT"
"dom X⊆Domain R ⟹ ⇑R (REST X) = REST (λa. Sup {X c| c. (c,a)∈R})"
"¬(dom X⊆Domain R) ⟹ ⇑R (REST X) = FAILT"
unfolding abs_fun_def by (auto split: nrest.split)
context fixes R assumes SV: "single_valued R" begin
lemma
fixes m :: "'b ⇒ enat option"
shows
Sup_sv: "(c, a') ∈ R ⟹ Sup {m a| a. (c,a) ∈ R} = m a'"
proof -
assume "(c,a') ∈ R"
with SV have singleton: "{m a| a. (c,a) ∈ R} = {m a'}" by(auto dest: single_valuedD)
show ?thesis unfolding singleton by simp
qed
lemma indomD: " M c = Some y ⟹ dom M ⊆ Domain R ⟹ (∃a. (c,a)∈R)"
by auto
lemma conc_abs_swap: "m' ≤ ⇓R m ⟷ ⇑R m' ≤ m"
proof(cases m; cases m')
fix M M'
note [simp] = conc_fun_def abs_fun_def
assume b[simp]: "m = REST M" "m' = REST M'"
show ?thesis
proof
assume a: "m' ≤ ⇓ R m"
from a b have R: "m' ≤ REST (λc. ⨆ {M a |a. (c, a) ∈ R})"
using conc_fun_RES by metis
with R have Domain: "dom M' ⊆ Domain R"
by (auto simp add: le_fun_def Sup_option_def split: if_splits option.splits)
from R have " M' x' ≤ M x" if "(x',x) ∈ R" for x x'
by (auto simp add: Sup_sv[OF that] intro: le_funI dest: le_funD[of _ _ x'])
with R SV Domain show "⇑ R m' ≤ m"
by (auto intro!: le_funI simp add: Sup_le_iff)
next
assume a: "⇑ R m' ≤ m"
show "m' ≤ ⇓R m"
proof(cases "dom M' ⊆ Domain R")
case True
have "M' x ≤ ⨆ {M a |a. (x, a) ∈ R}" for x
proof(cases "M' x")
case (Some y)
with True obtain x' where x_x': "(x,x') ∈ R"
by blast
with a SV show ?thesis
by (force simp add: Sup_sv[OF x_x'] Sup_le_iff dest!: le_funD[of _ _ x'] split: if_splits)
qed auto
then show "m' ≤ ⇓ R m"
by (auto intro!: le_funI)
next
case False
with a show ?thesis
by auto
qed
qed
qed (auto simp add: conc_fun_def abs_fun_def)
lemma
fixes m :: "'b ⇒ enat option"
shows
Inf_sv: "(c, a') ∈ R ⟹ Inf {m a| a. (c,a) ∈ R} = m a'"
proof -
assume "(c,a') ∈ R"
with SV have singleton: "{m a| a. (c,a) ∈ R} = {m a'}" by(auto dest: single_valuedD)
show ?thesis unfolding singleton by simp
qed
lemma ac_galois: "galois_connection (⇑R) (⇓R)"
by (unfold_locales) (rule conc_abs_swap)
lemma
fixes m :: "'b ⇒ enat option"
shows Sup_some_svD: "Sup {m a |a. (c, a) ∈ R} = Some t' ⟹ (∃a. (c,a)∈R ∧ m a = Some t')"
by (frule Sup_Some) (use SV in ‹auto simp add: single_valued_def Sup_sv›)
end
lemma pw_abs_nofail[refine_pw_simps]:
"nofailT (⇑R M) ⟷ (nofailT M ∧ (∀x. (∃t. inresT M x t) ⟶ x∈Domain R))" (is "?l ⟷ ?r")
proof (cases M)
case FAILi
then show ?thesis
by auto
next
case [simp]: (REST m)
show ?thesis
proof
assume "?l"
then show ?r
by (auto simp: abs_fun_def split: if_splits)
next
assume a: ?r
with REST have "x∈Domain R" if "m x = Some y" for x y
proof-
have "enat 0 ≤ y"
by (simp add: enat_0)
with that REST a show ?thesis
by auto
qed
then show ?l
by (auto simp: abs_fun_def)
qed
qed
lemma pw_conc_nofail[refine_pw_simps]:
"nofailT (⇓R S) = nofailT S"
by (cases S) (auto simp: conc_fun_RES)
lemma "single_valued A ⟹ single_valued B ⟹ single_valued (A O B)"
by (simp add: single_valued_relcomp)
lemma Sup_enatoption_less2: " Sup X = Some ∞ ⟹ (∃x. Some x ∈ X ∧ enat t < x)"
using Sup_enat_less2
by (metis Sup_option_def in_these_eq option.distinct(1) option.sel)
lemma pw_conc_inres[refine_pw_simps]:
"inresT (⇓R S') s t = (nofailT S'
⟶ ((∃s'. (s,s')∈R ∧ inresT S' s' t)))" (is "?l ⟷ ?r")
proof(cases S')
case [simp]: (REST m')
show ?thesis
proof
assume a: ?l
from this obtain t' where t': "enat t ≤ t'" "⨆ {m' a |a. (s, a) ∈ R} = Some t'"
by (auto simp: conc_fun_RES)
then obtain a t'' where "(s, a) ∈ R" "m' a = Some t''" "enat t ≤ t''"
proof(cases t')
case (enat n)
with t' that[where t''=n] show ?thesis
by(auto dest: Sup_finite_enat)
next
case infinity
with t' that show ?thesis
by (force dest!: Sup_enatoption_less2[where t=t] simp add: less_le_not_le t'(1))
qed
then show ?r
by auto
next
assume a: ?r
then obtain s' t' where s'_t': "(s,s') ∈ R" "m' s' = Some t'" "enat t ≤ t'"
by (auto simp: conc_fun_RES)
then have "∃t'≥enat t. ⨆ {m' a |a. (s, a) ∈ R} ≥ Some t'"
by (intro exI[of _ t']) (force intro: Sup_upper)
then show ?l
by (auto simp: conc_fun_RES elim!: le_some_optE)
qed
qed simp
lemma sv_the: "single_valued R ⟹ (c,a) ∈ R ⟹ (THE a. (c, a) ∈ R) = a"
by (simp add: single_valued_def the_equality)
lemma
conc_fun_RES_sv:
assumes SV: "single_valued R"
shows "⇓R (REST X) = REST (λc. if c∈Domain R then X (THE a. (c,a)∈R) else None )"
using SV by (auto simp add: Sup_sv sv_the Domain_iff conc_fun_def bot_option_def
intro!: ext split: nrest.split)
lemma conc_fun_mono[simp, intro!]:
shows "mono (⇓R)"
by (rule monoI) (auto simp: pw_le_iff refine_pw_simps)
lemma conc_fun_R_mono:
assumes "R ⊆ R'"
shows "⇓R M ≤ ⇓R' M"
using assms
by (auto simp: pw_le_iff refine_pw_simps)
lemma SupSup_2: "Sup {m a |a. (c, a) ∈ R O S} = Sup {m a |a b. (b,a)∈S ∧ (c,b)∈R }"
proof -
have i: "⋀a. (c,a) ∈ R O S ⟷ (∃b. (b,a)∈S ∧ (c,b)∈R)" by auto
have "Sup {m a |a. (c, a) ∈ R O S} = Sup {m a |a. (∃b. (b,a)∈S ∧ (c,b)∈R)}"
unfolding i by auto
also have "... = Sup {m a |a b. (b,a)∈S ∧ (c,b)∈R}" by auto
finally show ?thesis .
qed
lemma
fixes m :: "'a ⇒ enat option"
shows SupSup: "Sup {Sup {m aa |aa. P a aa c} |a. Q a c} = Sup {m aa |a aa. P a aa c ∧ Q a c}"
by (rule antisym) (auto intro: Sup_least Sup_subset_mono Sup_upper2)
lemma
fixes m :: "'a ⇒ enat option"
shows
SupSup_1: "Sup {Sup {m aa |aa. (a, aa) ∈ S} |a. (c, a) ∈ R} = Sup {m aa |a aa. (a,aa)∈S ∧ (c,a)∈R}"
by(rule SupSup)
lemma conc_fun_chain:
shows "⇓R (⇓S M) = ⇓(R O S) M"
proof(cases M)
case [simp]: (REST x)
have "⨆ {⨆ {x aa |aa. (a, aa) ∈ S} |a. (c, a) ∈ R} = ⨆ {x a |a. (c, a) ∈ R O S}" for c
by (unfold SupSup_1 SupSup_2) meson
then show ?thesis
by (simp add: conc_fun_RES)
qed auto
lemma conc_fun_chain_sv:
assumes SVR: "single_valued R" and SVS: "single_valued S"
shows "⇓R (⇓S M) = ⇓(R O S) M"
using assms conc_fun_chain by blast
lemma conc_Id[simp]: "⇓Id = id"
unfolding conc_fun_def [abs_def] by (auto split: nrest.split)
lemma conc_fun_fail_iff[simp]:
"⇓R S = FAILT ⟷ S=FAILT"
"FAILT = ⇓R S ⟷ S=FAILT"
by (auto simp add: pw_eq_iff refine_pw_simps)
lemma conc_trans[trans]:
assumes A: "C ≤ ⇓R B" and B: "B ≤ ⇓R' A"
shows "C ≤ ⇓R (⇓R' A)"
using assms by (fastforce simp: pw_le_iff refine_pw_simps)
lemma conc_trans_sv:
assumes SV: "single_valued R" "single_valued R'"
and A: "C ≤ ⇓R B" and B: "B ≤ ⇓R' A"
shows "C ≤ ⇓R (⇓R' A)"
using assms by (fastforce simp: pw_le_iff refine_pw_simps)
text ‹WARNING: The order of the single statements is important here!›
lemma conc_trans_additional[trans]:
assumes "single_valued R"
shows
"⋀A B C. A≤⇓R B ⟹ B≤ C ⟹ A≤⇓R C"
"⋀A B C. A≤⇓Id B ⟹ B≤⇓R C ⟹ A≤⇓R C"
"⋀A B C. A≤⇓R B ⟹ B≤⇓Id C ⟹ A≤⇓R C"
"⋀A B C. A≤⇓Id B ⟹ B≤⇓Id C ⟹ A≤ C"
"⋀A B C. A≤⇓Id B ⟹ B≤ C ⟹ A≤ C"
"⋀A B C. A≤ B ⟹ B≤⇓Id C ⟹ A≤ C"
using assms conc_trans[where R=R and R'=Id]
by (auto intro: order_trans)
lemma RETURNT_refine:
assumes "(x,x')∈R"
shows "RETURNT x ≤ ⇓R (RETURNT x')"
using assms
by (auto simp: RETURNT_def conc_fun_RES le_fun_def Sup_upper)
lemma bindT_refine':
fixes R' :: "('a×'b) set" and R::"('c×'d) set"
assumes R1: "M ≤ ⇓ R' M'"
assumes R2: "⋀x x' t . ⟦ (x,x')∈R'; inresT M x t; inresT M' x' t;
nofailT M; nofailT M'
⟧ ⟹ f x ≤ ⇓ R (f' x')"
shows "bindT M (λx. f x) ≤ ⇓ R (bindT M' (λx'. f' x'))"
using assms
by (simp add: pw_le_iff refine_pw_simps) blast
lemma bindT_refine:
fixes R' :: "('a×'b) set" and R::"('c×'d) set"
assumes R1: "M ≤ ⇓ R' M'"
assumes R2: "⋀x x'. ⟦ (x,x')∈R' ⟧
⟹ f x ≤ ⇓ R (f' x')"
shows "bindT M (λx. f x) ≤ ⇓ R (bind M' (λx'. f' x'))"
apply (rule bindT_refine') using assms by auto
subsection ‹WHILET refine›
lemma RECT_refine:
assumes M: "mono2 body"
assumes R0: "(x,x')∈R"
assumes RS: "⋀f f' x x'. ⟦ ⋀x x'. (x,x')∈R ⟹ f x ≤⇓S (f' x'); (x,x')∈R ⟧
⟹ body f x ≤⇓S (body' f' x')"
shows "RECT (λf x. body f x) x ≤⇓S (RECT (λf' x'. body' f' x') x')"
proof(cases "mono2 body'")
case True
have "flatf_gfp body x ≤ ⇓ S (flatf_gfp body' x')"
by (rule flatf_fixp_transfer[where
fp'="flatf_gfp body"
and B'=body
and P="λx x'. (x',x)∈R",
OF _ _ flatf_ord.fixp_unfold[OF M[THEN trimonoD_flatf_ge]] R0])
(use True in ‹auto intro: RS dest: trimonoD_flatf_ge›)
then show ?thesis
by (auto simp add: M RECT_flat_gfp_def)
qed (auto simp add: RECT_flat_gfp_def)
lemma WHILET_refine:
assumes R0: "(x,x')∈R"
assumes COND_REF: "⋀x x'. ⟦ (x,x')∈R ⟧ ⟹ b x = b' x'"
assumes STEP_REF:
"⋀x x'. ⟦ (x,x')∈R; b x; b' x' ⟧ ⟹ f x ≤ ⇓R (f' x')"
shows "whileT b f x ≤ ⇓R (whileT b' f' x')"
unfolding whileT_def
apply (rule RECT_refine[OF _ R0])
subgoal by refine_mono
subgoal by (auto simp add: COND_REF STEP_REF RETURNT_refine intro: bindT_refine[where R'=R])
done
lemma SPECT_refines_conc_fun':
assumes a: "⋀m c. M = SPECT m
⟹ c ∈ dom n ⟹ (∃a. (c,a)∈R ∧ n c ≤ m a)"
shows "SPECT n ≤ ⇓ R M"
proof -
have "n c ≤ ⨆ {m a |a. (c, a) ∈ R}" if "M = SPECT m" for c m
proof (cases "c ∈ dom n")
case True
with that a obtain a where k: "(c,a)∈R" "n c ≤ m a" by blast
then show ?thesis
by (intro Sup_upper2) auto
next
case False
then show ?thesis
by (simp add: domIff)
qed
then show ?thesis
unfolding conc_fun_def by (auto simp add: le_fun_def split: nrest.split)
qed
lemma SPECT_refines_conc_fun:
assumes a: "⋀m c. (∃a. (c,a)∈R ∧ n c ≤ m a)"
shows "SPECT n ≤ ⇓ R (SPECT m)"
by (rule SPECT_refines_conc_fun') (use a in auto)
lemma conc_fun_br: "⇓ (br α I1) (SPECT (emb I2 t))
= (SPECT (emb (λx. I1 x ∧ I2 (α x)) t))"
unfolding conc_fun_RES
using Sup_Some by (auto simp: emb'_def br_def bot_option_def Sup_option_def)
end