Theory Query
subsection ‹Query›
theory Query
imports "Monad_QuasiBorel"
begin
declare [[coercion qbs_l]]
abbreviation qbs_real :: "real quasi_borel" (‹ℝ⇩Q›) where "ℝ⇩Q ≡ qbs_borel"
abbreviation qbs_ennreal :: "ennreal quasi_borel" (‹ℝ⇩Q⇩≥⇩0›) where "ℝ⇩Q⇩≥⇩0 ≡ qbs_borel"
abbreviation qbs_nat :: "nat quasi_borel" (‹ℕ⇩Q›) where "ℕ⇩Q ≡ qbs_count_space UNIV"
abbreviation qbs_bool :: "bool quasi_borel" (‹𝔹⇩Q›) where "𝔹⇩Q ≡ count_space⇩Q UNIV"
definition query :: "['a qbs_measure, 'a ⇒ ennreal] ⇒ 'a qbs_measure" where
"query ≡ (λs f. normalize_qbs (density_qbs s f))"
lemma query_qbs_morphism[qbs]: "query ∈ monadM_qbs X →⇩Q (X ⇒⇩Q qbs_borel) ⇒⇩Q monadM_qbs X"
by(simp add: query_def)
definition "condition ≡ (λs P. query s (λx. if P x then 1 else 0))"
lemma condition_qbs_morphism[qbs]: "condition ∈ monadM_qbs X ⇒⇩Q (X ⇒⇩Q 𝔹⇩Q) ⇒⇩Q monadM_qbs X"
by(simp add: condition_def)
lemma condition_morphismP:
assumes "⋀x. x ∈ qbs_space X ⟹ 𝒫(y in qbs_l (s x). P x y) ≠ 0"
and [qbs]: "s ∈ X →⇩Q monadP_qbs Y" "P ∈ X →⇩Q Y ⇒⇩Q qbs_count_space UNIV"
shows "(λx. condition (s x) (P x)) ∈ X →⇩Q monadP_qbs Y"
proof(rule qbs_morphism_cong'[where f="λx. normalize_qbs (density_qbs (s x) (indicator {y∈qbs_space Y. P x y}))"])
fix x
assume x[qbs]:"x ∈ qbs_space X"
have "density_qbs (s x) (indicator {y ∈ qbs_space Y. P x y}) = density_qbs (s x) (λy. if P x y then 1 else 0)"
by(auto intro!: density_qbs_cong[OF qbs_space_monadPM[OF qbs_morphism_space[OF assms(2) x]]] indicator_qbs_morphism'')
thus "normalize_qbs (density_qbs (s x) (indicator {y ∈ qbs_space Y. P x y})) = condition (s x) (P x)"
unfolding condition_def query_def by simp
next
show "(λx. normalize_qbs (density_qbs (s x) (indicator {y ∈ qbs_space Y. P x y}))) ∈ X →⇩Q monadP_qbs Y"
proof(rule normalize_qbs_morphismP[of "λx. density_qbs (s x) (indicator {y ∈ qbs_space Y. P x y})"])
show "(λx. density_qbs (s x) (indicator {y ∈ qbs_space Y. P x y})) ∈ X →⇩Q monadM_qbs Y"
using qbs_morphism_monadPD[OF assms(2)] by simp
next
fix x
assume x:"x ∈ qbs_space X"
show "emeasure (qbs_l (density_qbs (s x) (indicator {y ∈ qbs_space Y. P x y}))) (qbs_space Y) ≠ 0"
"emeasure (qbs_l (density_qbs (s x) (indicator {y ∈ qbs_space Y. P x y}))) (qbs_space Y) ≠ ∞"
using assms(1)[OF x] qbs_l_monadP_le1[OF qbs_morphism_space[OF assms(2) x]]
by(auto simp add: qbs_l_density_qbs_indicator[OF qbs_space_monadPM[OF qbs_morphism_space[OF assms(2) x]] qbs_morphism_space[OF assms(3) x]] measure_def space_qbs_l_in[OF qbs_space_monadPM[OF qbs_morphism_space[OF assms(2) x]]])
qed
qed
lemma query_Bayes:
assumes [qbs]: "s ∈ qbs_space (monadP_qbs X)" "qbs_pred X P" "qbs_pred X Q"
shows "𝒫(x in condition s P. Q x) = 𝒫(x in s. Q x ¦ P x)" (is "?lhs = ?pq")
proof -
have X: "qbs_space X ≠ {}"
using assms(1) by(simp only: monadP_qbs_empty_iff[of X]) blast
note s[qbs] = qbs_space_monadPM[OF assms(1)]
have density_eq: "density_qbs s (λx. if P x then 1 else 0) = density_qbs s (indicator {x∈qbs_space X. P x})"
by(auto intro!: density_qbs_cong[of _ X] indicator_qbs_morphism'')
consider "emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X) = 0" | "emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X) ≠ 0" by auto
then show ?thesis
proof cases
case 1
have 2:"normalize_qbs (density_qbs s (λx. if P x then 1 else 0)) = qbs_null_measure X"
by(rule normalize_qbs0) (auto simp: 1)
have "𝒫(ω in qbs_l s. P ω) = measure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)"
by(simp add: space_qbs_l_in[OF s] measure_def density_eq qbs_l_density_qbs_indicator[OF s])
also have "... = 0"
by(simp add: measure_def 1)
finally show ?thesis
by(auto simp: condition_def query_def cond_prob_def 2 1 qbs_null_measure_null_measure[OF X])
next
case 1[simp]:2
from rep_qbs_space_monadP[OF assms(1)]
obtain α μ where hs: "s = ⟦X, α, μ⟧⇩s⇩f⇩i⇩n" "qbs_prob X α μ" by auto
then interpret qp: qbs_prob X α μ by simp
have [measurable]:"Measurable.pred (qbs_to_measure X) P" "Measurable.pred (qbs_to_measure X) Q"
using assms(2,3) by(simp_all add: lr_adjunction_correspondence)
have 2[simp]: "emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X) ≠ ⊤"
by(simp add: hs(1) qp.density_qbs qbs_s_finite.qbs_l[OF qp.density_qbs_s_finite] emeasure_distr emeasure_distr[where N="qbs_to_measure X",OF _ sets.top,simplified space_L] emeasure_density,rule order.strict_implies_not_eq[OF order.strict_trans1[OF qp.nn_integral_le_const[of 1] ennreal_one_less_top]]) auto
have 3: "measure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X) > 0"
using 2 emeasure_eq_ennreal_measure zero_less_measure_iff by fastforce
have "query s (λx. if P x then 1 else 0) = density_qbs (density_qbs s (λx. if P x then 1 else 0)) (λx. 1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X))"
unfolding query_def by(rule normalize_qbs) auto
also have "... = density_qbs s (λx. (if P x then 1 else 0) * (1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)))"
by(simp add: density_qbs_density_qbs_eq[OF qbs_space_monadPM[OF assms(1)]])
finally have query:"query s (λx. if P x then 1 else 0) = ..." .
have "?lhs = measure (density (qbs_l s) (λx. (if P x then 1 else 0) * (1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)))) {x ∈ space (qbs_l s). Q x}"
by(simp add: condition_def query qbs_l_density_qbs[OF qbs_space_monadPM[OF assms(1)]])
also have "... = measure (density μ (λx. (if P (α x) then 1 else 0) * (1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)))) {y. α y ∈ space (qbs_to_measure X) ∧ Q (α y)}"
by(simp add: hs(1) qp.qbs_l density_distr measure_def emeasure_distr)
also have "... = measure (density μ (λx. indicator {r. P (α r)} x * (1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)))) {y. Q (α y)}"
proof -
have [simp]:"(if P (α r) then 1 else 0) = indicator {r. P (α r)} r " for r
by auto
thus ?thesis by(simp add: space_L)
qed
also have "... = enn2real (1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)) * measure μ {r. P (α r) ∧ Q (α r)}"
proof -
have n_inf: "1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X) ≠ ∞"
using 1 by(auto simp: ennreal_divide_eq_top_iff)
show ?thesis
by(simp add: measure_density_times[OF _ _ n_inf] Collect_conj_eq)
qed
also have "... = (1 / measure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)) * qp.prob {r. P (α r) ∧ Q (α r)}"
proof -
have "1 / emeasure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X) = ennreal (1 / measure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X))"
by(auto simp add: emeasure_eq_ennreal_measure[OF 2] ennreal_1[symmetric] simp del: ennreal_1 intro!: divide_ennreal) (simp_all add: 3)
thus ?thesis by simp
qed also have "... = ?pq"
proof -
have qp:"𝒫(x in s. Q x ∧ P x) = qp.prob {r. P (α r) ∧ Q (α r)}"
by(auto simp: hs(1) qp.qbs_l measure_def emeasure_distr, simp add: space_L) meson
note sets = sets_qbs_l[OF qbs_space_monadPM[OF assms(1)],measurable_cong]
have [simp]: "density (qbs_l s) (λx. if P x then 1 else 0) = density (qbs_l s) (indicator {x∈space (qbs_to_measure X). P x})"
by(auto intro!: density_cong) (auto simp: indicator_def space_L sets_eq_imp_space_eq[OF sets])
have p: "𝒫(x in s. P x) = measure (qbs_l (density_qbs s (λx. if P x then 1 else 0))) (qbs_space X)"
by(auto simp: qbs_l_density_qbs[OF qbs_space_monadPM[OF assms(1),qbs]]) (auto simp: measure_restricted[of "{x ∈ space (qbs_to_measure X). P x}" "qbs_l s",simplified sets,OF _ sets.top,simplified,simplified space_L] space_L sets_eq_imp_space_eq[OF sets])
thus ?thesis
by(simp add: qp p cond_prob_def)
qed
finally show ?thesis .
qed
qed
lemma qbs_pmf_cond_pmf:
fixes p :: "'a :: countable pmf"
assumes "set_pmf p ∩ {x. P x} ≠ {}"
shows "condition (qbs_pmf p) P = qbs_pmf (cond_pmf p {x. P x})"
proof(rule inj_onD[OF qbs_l_inj[of "count_space UNIV"]])
note count_space_count_space_qbs_morphism[of P,qbs]
show g1:"condition (qbs_pmf p) P ∈ qbs_space (monadM_qbs (count_space⇩Q UNIV))" "qbs_pmf (cond_pmf p {x. P x}) ∈ qbs_space (monadM_qbs (count_space⇩Q UNIV))"
by auto
show "qbs_l (condition (qbs_pmf p) P) = qbs_l (qbs_pmf (cond_pmf p {x. P x}))"
proof(safe intro!: measure_eqI_countable)
fix a
have "condition (qbs_pmf p) P = normalize_qbs (density_qbs (qbs_pmf p) (λx. if P x then 1 else 0))"
by(auto simp: condition_def query_def)
also have "... = density_qbs (density_qbs (qbs_pmf p) (λx. if P x then 1 else 0)) (λx. 1 / emeasure (qbs_l (density_qbs (qbs_pmf p) (λx. if P x then 1 else 0))) (qbs_space (count_space⇩Q UNIV)))"
proof -
have 1:"(∫⇧+ x. ennreal (pmf p x) * (if P x then 1 else 0) ∂count_space UNIV) = (∫⇧+ x∈{x. P x}. ennreal (pmf p x) ∂count_space UNIV)"
by(auto intro!: nn_integral_cong)
have "... > 0"
using assms(1) by(force intro!: nn_integral_less[of "λx. 0",simplified] simp: AE_count_space set_pmf_eq' indicator_def)
hence 2:"(∫⇧+x∈{x. P x}. ennreal (pmf p x) ∂count_space UNIV) ≠ 0"
by auto
have 3:"(∫⇧+ x∈{x. P x}. ennreal (pmf p x) ∂count_space UNIV) ≠ ⊤"
proof -
have "(∫⇧+ x∈{x. P x}. ennreal (pmf p x) ∂count_space UNIV) ≤ (∫⇧+ x. ennreal (pmf p x) ∂count_space UNIV)"
by(auto intro!: nn_integral_mono simp: indicator_def)
also have "... = 1"
by (simp add: nn_integral_pmf_eq_1)
finally show ?thesis
using ennreal_one_neq_top neq_top_trans by fastforce
qed
show ?thesis
by(rule normalize_qbs) (auto simp: qbs_l_density_qbs[of _ "count_space UNIV"] emeasure_density nn_integral_measure_pmf 1 2 3)
qed
also have "... = density_qbs (qbs_pmf p) (λx. (if P x then 1 else 0) * (1 / (∫⇧+ x. ennreal (pmf p x) * (if P x then 1 else 0) ∂count_space UNIV)))"
by(simp add: density_qbs_density_qbs_eq[of _ "count_space UNIV"] qbs_l_density_qbs[of _ "count_space UNIV"] emeasure_density nn_integral_measure_pmf)
also have "... = density_qbs (qbs_pmf p) (λx. (if P x then 1 else 0) * (1 / (emeasure (measure_pmf p) (Collect P))))"
proof -
have [simp]: "(∫⇧+ x. ennreal (pmf p x) * (if P x then 1 else 0) ∂count_space UNIV) = emeasure (measure_pmf p) (Collect P)" (is "?l = ?r")
proof -
have "?l = (∫⇧+ x. ennreal (pmf p x) * (if P x then 1 else 0) ∂count_space {x. P x})"
by(rule nn_integral_count_space_eq) auto
also have "... = ?r"
by(auto simp: nn_integral_pmf[symmetric] intro!: nn_integral_cong)
finally show ?thesis .
qed
show ?thesis by simp
qed
finally show "emeasure (qbs_l (condition (qbs_pmf p) P)) {a} = emeasure (qbs_l (qbs_pmf (cond_pmf p {x. P x}))) {a}"
by(simp add: ennreal_divide_times qbs_l_density_qbs[of _ "count_space UNIV"] emeasure_density cond_pmf.rep_eq[OF assms(1)])
qed(auto simp: sets_qbs_l[OF g1(1)])
qed
subsubsection ‹\texttt{twoUs}›
text ‹ Example from Section~2 in @{cite Sato_2019}.›
definition "Uniform ≡ (λa b::real. uniform_qbs lborel_qbs {a<..<b})"
lemma Uniform_qbs[qbs]: "Uniform ∈ ℝ⇩Q ⇒⇩Q ℝ⇩Q ⇒⇩Q monadM_qbs ℝ⇩Q"
unfolding Uniform_def by (rule interval_uniform_qbs)
definition twoUs :: "(real × real) qbs_measure" where
"twoUs ≡ do {
let u1 = Uniform 0 1;
let u2 = Uniform 0 1;
let y = u1 ⨂⇩Q⇩m⇩e⇩s u2;
condition y (λ(x,y). x < 0.5 ∨ y > 0.5)
}"
lemma twoUs_qbs: "twoUs ∈ monadM_qbs (ℝ⇩Q ⨂⇩Q ℝ⇩Q)"
by(simp add: twoUs_def)
interpretation rr: standard_borel_ne "borel ⨂⇩M borel :: (real × real) measure"
by(simp add: borel_prod)
lemma qbs_l_Uniform[simp]: "a < b ⟹ qbs_l (Uniform a b) = uniform_measure lborel {a<..<b}"
by(simp add: standard_borel_ne.qbs_l_uniform_qbs[of borel lborel_qbs] Uniform_def)
lemma Uniform_qbsP:
assumes [arith]: "a < b"
shows "Uniform a b ∈ monadP_qbs ℝ⇩Q"
by(auto simp: monadP_qbs_def sub_qbs_space intro!: prob_space_uniform_measure)