# Theory Measurable

```(*  Title:      HOL/Analysis/Measurable.thy
Author:     Johannes Hölzl <hoelzl@in.tum.de>
*)
section ‹Measurability Prover›
theory Measurable
imports
Sigma_Algebra
"HOL-Library.Order_Continuity"
begin

lemma (in algebra) sets_Collect_finite_All:
assumes "⋀i. i ∈ S ⟹ {x∈Ω. P i x} ∈ M" "finite S"
shows "{x∈Ω. ∀i∈S. P i x} ∈ M"
proof -
have "{x∈Ω. ∀i∈S. P i x} = (if S = {} then Ω else ⋂i∈S. {x∈Ω. P i x})"
by auto
with assms show ?thesis by (auto intro!: sets_Collect_finite_All')
qed

abbreviation "pred M P ≡ P ∈ measurable M (count_space (UNIV::bool set))"

lemma pred_def: "pred M P ⟷ {x∈space M. P x} ∈ sets M"
proof
assume "pred M P"
then have "P -` {True} ∩ space M ∈ sets M"
by (auto simp: measurable_count_space_eq2)
also have "P -` {True} ∩ space M = {x∈space M. P x}" by auto
finally show "{x∈space M. P x} ∈ sets M" .
next
assume P: "{x∈space M. P x} ∈ sets M"
moreover
{ fix X
have "X ∈ Pow (UNIV :: bool set)" by simp
then have "P -` X ∩ space M = {x∈space M. ((X = {True} ⟶ P x) ∧ (X = {False} ⟶ ¬ P x) ∧ X ≠ {})}"
unfolding UNIV_bool Pow_insert Pow_empty by auto
then have "P -` X ∩ space M ∈ sets M"
by (auto intro!: sets.sets_Collect_neg sets.sets_Collect_imp sets.sets_Collect_conj sets.sets_Collect_const P) }
then show "pred M P"
by (auto simp: measurable_def)
qed

lemma pred_sets1: "{x∈space M. P x} ∈ sets M ⟹ f ∈ measurable N M ⟹ pred N (λx. P (f x))"
by (rule measurable_compose[where f=f and N=M]) (auto simp: pred_def)

lemma pred_sets2: "A ∈ sets N ⟹ f ∈ measurable M N ⟹ pred M (λx. f x ∈ A)"
by (rule measurable_compose[where f=f and N=N]) (auto simp: pred_def Int_def[symmetric])

ML_file ‹measurable.ML›

attribute_setup measurable = ‹
Scan.lift (
(Args.add >> K true || Args.del >> K false || Scan.succeed true) --
Scan.optional (Args.parens (
Scan.optional (Args.\$\$\$ "raw" >> K true) false --
Scan.optional (Args.\$\$\$ "generic" >> K Measurable.Generic) Measurable.Concrete))
(false, Measurable.Concrete) >>
Measurable.measurable_thm_attr)
› "declaration of measurability theorems"

attribute_setup measurable_dest = Measurable.dest_thm_attr
"add dest rule to measurability prover"

attribute_setup measurable_cong = Measurable.cong_thm_attr
"add congurence rules to measurability prover"

method_setup✐‹tag important› measurable = ‹ Scan.lift (Scan.succeed (METHOD o Measurable.measurable_tac)) ›
"measurability prover"

simproc_setup✐‹tag important› measurable ("A ∈ sets M" | "f ∈ measurable M N") = ‹K Measurable.simproc›

setup ‹
›

declare
pred_sets1[measurable_dest]
pred_sets2[measurable_dest]
sets.sets_into_space[measurable_dest]

declare
sets.top[measurable]
sets.empty_sets[measurable (raw)]
sets.Un[measurable (raw)]
sets.Diff[measurable (raw)]

declare
measurable_count_space[measurable (raw)]
measurable_ident[measurable (raw)]
measurable_id[measurable (raw)]
measurable_const[measurable (raw)]
measurable_If[measurable (raw)]
measurable_comp[measurable (raw)]
measurable_sets[measurable (raw)]

declare measurable_cong_sets[measurable_cong]
declare sets_restrict_space_cong[measurable_cong]
declare sets_restrict_UNIV[measurable_cong]

lemma predE[measurable (raw)]:
"pred M P ⟹ {x∈space M. P x} ∈ sets M"
unfolding pred_def .

lemma pred_intros_imp'[measurable (raw)]:
"(K ⟹ pred M (λx. P x)) ⟹ pred M (λx. K ⟶ P x)"
by (cases K) auto

lemma pred_intros_conj1'[measurable (raw)]:
"(K ⟹ pred M (λx. P x)) ⟹ pred M (λx. K ∧ P x)"
by (cases K) auto

lemma pred_intros_conj2'[measurable (raw)]:
"(K ⟹ pred M (λx. P x)) ⟹ pred M (λx. P x ∧ K)"
by (cases K) auto

lemma pred_intros_disj1'[measurable (raw)]:
"(¬ K ⟹ pred M (λx. P x)) ⟹ pred M (λx. K ∨ P x)"
by (cases K) auto

lemma pred_intros_disj2'[measurable (raw)]:
"(¬ K ⟹ pred M (λx. P x)) ⟹ pred M (λx. P x ∨ K)"
by (cases K) auto

lemma pred_intros_logic[measurable (raw)]:
"pred M (λx. x ∈ space M)"
"pred M (λx. P x) ⟹ pred M (λx. ¬ P x)"
"pred M (λx. Q x) ⟹ pred M (λx. P x) ⟹ pred M (λx. Q x ∧ P x)"
"pred M (λx. Q x) ⟹ pred M (λx. P x) ⟹ pred M (λx. Q x ⟶ P x)"
"pred M (λx. Q x) ⟹ pred M (λx. P x) ⟹ pred M (λx. Q x ∨ P x)"
"pred M (λx. Q x) ⟹ pred M (λx. P x) ⟹ pred M (λx. Q x = P x)"
"pred M (λx. f x ∈ UNIV)"
"pred M (λx. f x ∈ {})"
"pred M (λx. P' (f x) x) ⟹ pred M (λx. f x ∈ {y. P' y x})"
"pred M (λx. f x ∈ (B x)) ⟹ pred M (λx. f x ∈ - (B x))"
"pred M (λx. f x ∈ (A x)) ⟹ pred M (λx. f x ∈ (B x)) ⟹ pred M (λx. f x ∈ (A x) - (B x))"
"pred M (λx. f x ∈ (A x)) ⟹ pred M (λx. f x ∈ (B x)) ⟹ pred M (λx. f x ∈ (A x) ∩ (B x))"
"pred M (λx. f x ∈ (A x)) ⟹ pred M (λx. f x ∈ (B x)) ⟹ pred M (λx. f x ∈ (A x) ∪ (B x))"
"pred M (λx. g x (f x) ∈ (X x)) ⟹ pred M (λx. f x ∈ (g x) -` (X x))"
by (auto simp: iff_conv_conj_imp pred_def)

lemma pred_intros_countable[measurable (raw)]:
fixes P :: "'a ⇒ 'i :: countable ⇒ bool"
shows
"(⋀i. pred M (λx. P x i)) ⟹ pred M (λx. ∀i. P x i)"
"(⋀i. pred M (λx. P x i)) ⟹ pred M (λx. ∃i. P x i)"
by (auto intro!: sets.sets_Collect_countable_All sets.sets_Collect_countable_Ex simp: pred_def)

lemma pred_intros_countable_bounded[measurable (raw)]:
fixes X :: "'i :: countable set"
shows
"(⋀i. i ∈ X ⟹ pred M (λx. x ∈ N x i)) ⟹ pred M (λx. x ∈ (⋂i∈X. N x i))"
"(⋀i. i ∈ X ⟹ pred M (λx. x ∈ N x i)) ⟹ pred M (λx. x ∈ (⋃i∈X. N x i))"
"(⋀i. i ∈ X ⟹ pred M (λx. P x i)) ⟹ pred M (λx. ∀i∈X. P x i)"
"(⋀i. i ∈ X ⟹ pred M (λx. P x i)) ⟹ pred M (λx. ∃i∈X. P x i)"
by simp_all (auto simp: Bex_def Ball_def)

lemma pred_intros_finite[measurable (raw)]:
"finite I ⟹ (⋀i. i ∈ I ⟹ pred M (λx. x ∈ N x i)) ⟹ pred M (λx. x ∈ (⋂i∈I. N x i))"
"finite I ⟹ (⋀i. i ∈ I ⟹ pred M (λx. x ∈ N x i)) ⟹ pred M (λx. x ∈ (⋃i∈I. N x i))"
"finite I ⟹ (⋀i. i ∈ I ⟹ pred M (λx. P x i)) ⟹ pred M (λx. ∀i∈I. P x i)"
"finite I ⟹ (⋀i. i ∈ I ⟹ pred M (λx. P x i)) ⟹ pred M (λx. ∃i∈I. P x i)"
by (auto intro!: sets.sets_Collect_finite_Ex sets.sets_Collect_finite_All simp: iff_conv_conj_imp pred_def)

lemma countable_Un_Int[measurable (raw)]:
"(⋀i :: 'i :: countable. i ∈ I ⟹ N i ∈ sets M) ⟹ (⋃i∈I. N i) ∈ sets M"
"I ≠ {} ⟹ (⋀i :: 'i :: countable. i ∈ I ⟹ N i ∈ sets M) ⟹ (⋂i∈I. N i) ∈ sets M"
by auto

declare
finite_UN[measurable (raw)]
finite_INT[measurable (raw)]

lemma sets_Int_pred[measurable (raw)]:
assumes space: "A ∩ B ⊆ space M" and [measurable]: "pred M (λx. x ∈ A)" "pred M (λx. x ∈ B)"
shows "A ∩ B ∈ sets M"
proof -
have "{x∈space M. x ∈ A ∩ B} ∈ sets M" by auto
also have "{x∈space M. x ∈ A ∩ B} = A ∩ B"
using space by auto
finally show ?thesis .
qed

lemma [measurable (raw generic)]:
assumes f: "f ∈ measurable M N" and c: "c ∈ space N ⟹ {c} ∈ sets N"
shows pred_eq_const1: "pred M (λx. f x = c)"
and pred_eq_const2: "pred M (λx. c = f x)"
proof -
show "pred M (λx. f x = c)"
proof cases
assume "c ∈ space N"
with measurable_sets[OF f c] show ?thesis
by (auto simp: Int_def conj_commute pred_def)
next
assume "c ∉ space N"
with f[THEN measurable_space] have "{x ∈ space M. f x = c} = {}" by auto
then show ?thesis by (auto simp: pred_def cong: conj_cong)
qed
then show "pred M (λx. c = f x)"
qed

lemma pred_count_space_const1[measurable (raw)]:
"f ∈ measurable M (count_space UNIV) ⟹ Measurable.pred M (λx. f x = c)"
by (intro pred_eq_const1[where N="count_space UNIV"]) (auto )

lemma pred_count_space_const2[measurable (raw)]:
"f ∈ measurable M (count_space UNIV) ⟹ Measurable.pred M (λx. c = f x)"
by (intro pred_eq_const2[where N="count_space UNIV"]) (auto )

lemma pred_le_const[measurable (raw generic)]:
assumes f: "f ∈ measurable M N" and c: "{.. c} ∈ sets N" shows "pred M (λx. f x ≤ c)"
using measurable_sets[OF f c]
by (auto simp: Int_def conj_commute eq_commute pred_def)

lemma pred_const_le[measurable (raw generic)]:
assumes f: "f ∈ measurable M N" and c: "{c ..} ∈ sets N" shows "pred M (λx. c ≤ f x)"
using measurable_sets[OF f c]
by (auto simp: Int_def conj_commute eq_commute pred_def)

lemma pred_less_const[measurable (raw generic)]:
assumes f: "f ∈ measurable M N" and c: "{..< c} ∈ sets N" shows "pred M (λx. f x < c)"
using measurable_sets[OF f c]
by (auto simp: Int_def conj_commute eq_commute pred_def)

lemma pred_const_less[measurable (raw generic)]:
assumes f: "f ∈ measurable M N" and c: "{c <..} ∈ sets N" shows "pred M (λx. c < f x)"
using measurable_sets[OF f c]
by (auto simp: Int_def conj_commute eq_commute pred_def)

declare
sets.Int[measurable (raw)]

lemma pred_in_If[measurable (raw)]:
"(P ⟹ pred M (λx. x ∈ A x)) ⟹ (¬ P ⟹ pred M (λx. x ∈ B x)) ⟹
pred M (λx. x ∈ (if P then A x else B x))"
by auto

lemma sets_range[measurable_dest]:
"A ` I ⊆ sets M ⟹ i ∈ I ⟹ A i ∈ sets M"
by auto

lemma pred_sets_range[measurable_dest]:
"A ` I ⊆ sets N ⟹ i ∈ I ⟹ f ∈ measurable M N ⟹ pred M (λx. f x ∈ A i)"
using pred_sets2[OF sets_range] by auto

lemma sets_All[measurable_dest]:
"∀i. A i ∈ sets (M i) ⟹ A i ∈ sets (M i)"
by auto

lemma pred_sets_All[measurable_dest]:
"∀i. A i ∈ sets (N i) ⟹ f ∈ measurable M (N i) ⟹ pred M (λx. f x ∈ A i)"
using pred_sets2[OF sets_All, of A N f] by auto

lemma sets_Ball[measurable_dest]:
"∀i∈I. A i ∈ sets (M i) ⟹ i∈I ⟹ A i ∈ sets (M i)"
by auto

lemma pred_sets_Ball[measurable_dest]:
"∀i∈I. A i ∈ sets (N i) ⟹ i∈I ⟹ f ∈ measurable M (N i) ⟹ pred M (λx. f x ∈ A i)"
using pred_sets2[OF sets_Ball, of _ _ _ f] by auto

lemma measurable_finite[measurable (raw)]:
fixes S :: "'a ⇒ nat set"
assumes [measurable]: "⋀i. {x∈space M. i ∈ S x} ∈ sets M"
shows "pred M (λx. finite (S x))"
unfolding finite_nat_set_iff_bounded by (simp add: Ball_def)

lemma measurable_Least[measurable]:
assumes [measurable]: "(⋀i::nat. (λx. P i x) ∈ measurable M (count_space UNIV))"
shows "(λx. LEAST i. P i x) ∈ measurable M (count_space UNIV)"
unfolding measurable_def by (safe intro!: sets_Least) simp_all

lemma measurable_Max_nat[measurable (raw)]:
fixes P :: "nat ⇒ 'a ⇒ bool"
assumes [measurable]: "⋀i. Measurable.pred M (P i)"
shows "(λx. Max {i. P i x}) ∈ measurable M (count_space UNIV)"
unfolding measurable_count_space_eq2_countable
proof safe
fix n

{ fix x assume "∀i. ∃n≥i. P n x"
then have "infinite {i. P i x}"
unfolding infinite_nat_iff_unbounded_le by auto
then have "Max {i. P i x} = the None"
by (rule Max.infinite) }
note 1 = this

{ fix x i j assume "P i x" "∀n≥j. ¬ P n x"
then have "finite {i. P i x}"
by (auto simp: subset_eq not_le[symmetric] finite_nat_iff_bounded)
with ‹P i x› have "P (Max {i. P i x}) x" "i ≤ Max {i. P i x}" "finite {i. P i x}"
using Max_in[of "{i. P i x}"] by auto }
note 2 = this

have "(λx. Max {i. P i x}) -` {n} ∩ space M = {x∈space M. Max {i. P i x} = n}"
by auto
also have "… =
{x∈space M. if (∀i. ∃n≥i. P n x) then the None = n else
if (∃i. P i x) then P n x ∧ (∀i>n. ¬ P i x)
else Max {} = n}"
by (intro arg_cong[where f=Collect] ext conj_cong)
(auto simp add: 1 2 not_le[symmetric] intro!: Max_eqI)
also have "… ∈ sets M"
by measurable
finally show "(λx. Max {i. P i x}) -` {n} ∩ space M ∈ sets M" .
qed simp

lemma measurable_Min_nat[measurable (raw)]:
fixes P :: "nat ⇒ 'a ⇒ bool"
assumes [measurable]: "⋀i. Measurable.pred M (P i)"
shows "(λx. Min {i. P i x}) ∈ measurable M (count_space UNIV)"
unfolding measurable_count_space_eq2_countable
proof safe
fix n

{ fix x assume "∀i. ∃n≥i. P n x"
then have "infinite {i. P i x}"
unfolding infinite_nat_iff_unbounded_le by auto
then have "Min {i. P i x} = the None"
by (rule Min.infinite) }
note 1 = this

{ fix x i j assume "P i x" "∀n≥j. ¬ P n x"
then have "finite {i. P i x}"
by (auto simp: subset_eq not_le[symmetric] finite_nat_iff_bounded)
with ‹P i x› have "P (Min {i. P i x}) x" "Min {i. P i x} ≤ i" "finite {i. P i x}"
using Min_in[of "{i. P i x}"] by auto }
note 2 = this

have "(λx. Min {i. P i x}) -` {n} ∩ space M = {x∈space M. Min {i. P i x} = n}"
by auto
also have "… =
{x∈space M. if (∀i. ∃n≥i. P n x) then the None = n else
if (∃i. P i x) then P n x ∧ (∀i<n. ¬ P i x)
else Min {} = n}"
by (intro arg_cong[where f=Collect] ext conj_cong)
(auto simp add: 1 2 not_le[symmetric] intro!: Min_eqI)
also have "… ∈ sets M"
by measurable
finally show "(λx. Min {i. P i x}) -` {n} ∩ space M ∈ sets M" .
qed simp

lemma measurable_count_space_insert[measurable (raw)]:
"s ∈ S ⟹ A ∈ sets (count_space S) ⟹ insert s A ∈ sets (count_space S)"
by simp

lemma sets_UNIV [measurable (raw)]: "A ∈ sets (count_space UNIV)"
by simp

lemma measurable_card[measurable]:
fixes S :: "'a ⇒ nat set"
assumes [measurable]: "⋀i. {x∈space M. i ∈ S x} ∈ sets M"
shows "(λx. card (S x)) ∈ measurable M (count_space UNIV)"
unfolding measurable_count_space_eq2_countable
proof safe
fix n show "(λx. card (S x)) -` {n} ∩ space M ∈ sets M"
proof (cases n)
case 0
then have "(λx. card (S x)) -` {n} ∩ space M = {x∈space M. infinite (S x) ∨ (∀i. i ∉ S x)}"
by auto
also have "… ∈ sets M"
by measurable
finally show ?thesis .
next
case (Suc i)
then have "(λx. card (S x)) -` {n} ∩ space M =
(⋃F∈{A∈{A. finite A}. card A = n}. {x∈space M. (∀i. i ∈ S x ⟷ i ∈ F)})"
unfolding set_eq_iff[symmetric] Collect_bex_eq[symmetric] by (auto intro: card_ge_0_finite)
also have "… ∈ sets M"
by (intro sets.countable_UN' countable_Collect countable_Collect_finite) auto
finally show ?thesis .
qed
qed rule

lemma measurable_pred_countable[measurable (raw)]:
assumes "countable X"
shows
"(⋀i. i ∈ X ⟹ Measurable.pred M (λx. P x i)) ⟹ Measurable.pred M (λx. ∀i∈X. P x i)"
"(⋀i. i ∈ X ⟹ Measurable.pred M (λx. P x i)) ⟹ Measurable.pred M (λx. ∃i∈X. P x i)"
unfolding pred_def
by (auto intro!: sets.sets_Collect_countable_All' sets.sets_Collect_countable_Ex' assms)

subsection✐‹tag unimportant› ‹Measurability for (co)inductive predicates›

lemma measurable_bot[measurable]: "bot ∈ measurable M (count_space UNIV)"

lemma measurable_top[measurable]: "top ∈ measurable M (count_space UNIV)"

lemma measurable_SUP[measurable]:
fixes F :: "'i ⇒ 'a ⇒ 'b::{complete_lattice, countable}"
assumes [simp]: "countable I"
assumes [measurable]: "⋀i. i ∈ I ⟹ F i ∈ measurable M (count_space UNIV)"
shows "(λx. SUP i∈I. F i x) ∈ measurable M (count_space UNIV)"
unfolding measurable_count_space_eq2_countable
proof (safe intro!: UNIV_I)
fix a
have "(λx. SUP i∈I. F i x) -` {a} ∩ space M =
{x∈space M. (∀i∈I. F i x ≤ a) ∧ (∀b. (∀i∈I. F i x ≤ b) ⟶ a ≤ b)}"
unfolding SUP_le_iff[symmetric] by auto
also have "… ∈ sets M"
by measurable
finally show "(λx. SUP i∈I. F i x) -` {a} ∩ space M ∈ sets M" .
qed

lemma measurable_INF[measurable]:
fixes F :: "'i ⇒ 'a ⇒ 'b::{complete_lattice, countable}"
assumes [simp]: "countable I"
assumes [measurable]: "⋀i. i ∈ I ⟹ F i ∈ measurable M (count_space UNIV)"
shows "(λx. INF i∈I. F i x) ∈ measurable M (count_space UNIV)"
unfolding measurable_count_space_eq2_countable
proof (safe intro!: UNIV_I)
fix a
have "(λx. INF i∈I. F i x) -` {a} ∩ space M =
{x∈space M. (∀i∈I. a ≤ F i x) ∧ (∀b. (∀i∈I. b ≤ F i x) ⟶ b ≤ a)}"
unfolding le_INF_iff[symmetric] by auto
also have "… ∈ sets M"
by measurable
finally show "(λx. INF i∈I. F i x) -` {a} ∩ space M ∈ sets M" .
qed

lemma measurable_lfp_coinduct[consumes 1, case_names continuity step]:
fixes F :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b::{complete_lattice, countable})"
assumes "P M"
assumes F: "sup_continuous F"
assumes *: "⋀M A. P M ⟹ (⋀N. P N ⟹ A ∈ measurable N (count_space UNIV)) ⟹ F A ∈ measurable M (count_space UNIV)"
shows "lfp F ∈ measurable M (count_space UNIV)"
proof -
{ fix i from ‹P M› have "((F ^^ i) bot) ∈ measurable M (count_space UNIV)"
by (induct i arbitrary: M) (auto intro!: *) }
then have "(λx. SUP i. (F ^^ i) bot x) ∈ measurable M (count_space UNIV)"
by measurable
also have "(λx. SUP i. (F ^^ i) bot x) = lfp F"
by (subst sup_continuous_lfp) (auto intro: F simp: image_comp)
finally show ?thesis .
qed

lemma measurable_lfp:
fixes F :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b::{complete_lattice, countable})"
assumes F: "sup_continuous F"
assumes *: "⋀A. A ∈ measurable M (count_space UNIV) ⟹ F A ∈ measurable M (count_space UNIV)"
shows "lfp F ∈ measurable M (count_space UNIV)"
by (coinduction rule: measurable_lfp_coinduct[OF _ F]) (blast intro: *)

lemma measurable_gfp_coinduct[consumes 1, case_names continuity step]:
fixes F :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b::{complete_lattice, countable})"
assumes "P M"
assumes F: "inf_continuous F"
assumes *: "⋀M A. P M ⟹ (⋀N. P N ⟹ A ∈ measurable N (count_space UNIV)) ⟹ F A ∈ measurable M (count_space UNIV)"
shows "gfp F ∈ measurable M (count_space UNIV)"
proof -
{ fix i from ‹P M› have "((F ^^ i) top) ∈ measurable M (count_space UNIV)"
by (induct i arbitrary: M) (auto intro!: *) }
then have "(λx. INF i. (F ^^ i) top x) ∈ measurable M (count_space UNIV)"
by measurable
also have "(λx. INF i. (F ^^ i) top x) = gfp F"
by (subst inf_continuous_gfp) (auto intro: F simp: image_comp)
finally show ?thesis .
qed

lemma measurable_gfp:
fixes F :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b::{complete_lattice, countable})"
assumes F: "inf_continuous F"
assumes *: "⋀A. A ∈ measurable M (count_space UNIV) ⟹ F A ∈ measurable M (count_space UNIV)"
shows "gfp F ∈ measurable M (count_space UNIV)"
by (coinduction rule: measurable_gfp_coinduct[OF _ F]) (blast intro: *)

lemma measurable_lfp2_coinduct[consumes 1, case_names continuity step]:
fixes F :: "('a ⇒ 'c ⇒ 'b) ⇒ ('a ⇒ 'c ⇒ 'b::{complete_lattice, countable})"
assumes "P M s"
assumes F: "sup_continuous F"
assumes *: "⋀M A s. P M s ⟹ (⋀N t. P N t ⟹ A t ∈ measurable N (count_space UNIV)) ⟹ F A s ∈ measurable M (count_space UNIV)"
shows "lfp F s ∈ measurable M (count_space UNIV)"
proof -
{ fix i from ‹P M s› have "(λx. (F ^^ i) bot s x) ∈ measurable M (count_space UNIV)"
by (induct i arbitrary: M s) (auto intro!: *) }
then have "(λx. SUP i. (F ^^ i) bot s x) ∈ measurable M (count_space UNIV)"
by measurable
also have "(λx. SUP i. (F ^^ i) bot s x) = lfp F s"
by (subst sup_continuous_lfp) (auto simp: F simp: image_comp)
finally show ?thesis .
qed

lemma measurable_gfp2_coinduct[consumes 1, case_names continuity step]:
fixes F :: "('a ⇒ 'c ⇒ 'b) ⇒ ('a ⇒ 'c ⇒ 'b::{complete_lattice, countable})"
assumes "P M s"
assumes F: "inf_continuous F"
assumes *: "⋀M A s. P M s ⟹ (⋀N t. P N t ⟹ A t ∈ measurable N (count_space UNIV)) ⟹ F A s ∈ measurable M (count_space UNIV)"
shows "gfp F s ∈ measurable M (count_space UNIV)"
proof -
{ fix i from ‹P M s› have "(λx. (F ^^ i) top s x) ∈ measurable M (count_space UNIV)"
by (induct i arbitrary: M s) (auto intro!: *) }
then have "(λx. INF i. (F ^^ i) top s x) ∈ measurable M (count_space UNIV)"
by measurable
also have "(λx. INF i. (F ^^ i) top s x) = gfp F s"
by (subst inf_continuous_gfp) (auto simp: F simp: image_comp)
finally show ?thesis .
qed

lemma measurable_enat_coinduct:
fixes f :: "'a ⇒ enat"
assumes "R f"
assumes *: "⋀f. R f ⟹ ∃g h i P. R g ∧ f = (λx. if P x then h x else eSuc (g (i x))) ∧
Measurable.pred M P ∧
i ∈ measurable M M ∧
h ∈ measurable M (count_space UNIV)"
shows "f ∈ measurable M (count_space UNIV)"
proof (simp add: measurable_count_space_eq2_countable, rule )
fix a :: enat
have "f -` {a} ∩ space M = {x∈space M. f x = a}"
by auto
{ fix i :: nat
from ‹R f› have "Measurable.pred M (λx. f x = enat i)"
proof (induction i arbitrary: f)
case 0
from *[OF this] obtain g h i P
where f: "f = (λx. if P x then h x else eSuc (g (i x)))" and
[measurable]: "Measurable.pred M P" "i ∈ measurable M M" "h ∈ measurable M (count_space UNIV)"
by auto
have "Measurable.pred M (λx. P x ∧ h x = 0)"
by measurable
also have "(λx. P x ∧ h x = 0) = (λx. f x = enat 0)"
by (auto simp: f zero_enat_def[symmetric])
finally show ?case .
next
case (Suc n)
from *[OF Suc.prems] obtain g h i P
where f: "f = (λx. if P x then h x else eSuc (g (i x)))" and "R g" and
M[measurable]: "Measurable.pred M P" "i ∈ measurable M M" "h ∈ measurable M (count_space UNIV)"
by auto
have "(λx. f x = enat (Suc n)) =
(λx. (P x ⟶ h x = enat (Suc n)) ∧ (¬ P x ⟶ g (i x) = enat n))"
by (auto simp: f zero_enat_def[symmetric] eSuc_enat[symmetric])
also have "Measurable.pred M …"
by (intro pred_intros_logic measurable_compose[OF M(2)] Suc ‹R g›) measurable
finally show ?case .
qed
then have "f -` {enat i} ∩ space M ∈ sets M"
by (simp add: pred_def Int_def conj_commute) }
note fin = this
show "f -` {a} ∩ space M ∈ sets M"
proof (cases a)
case infinity
then have "f -` {a} ∩ space M = space M - (⋃n. f -` {enat n} ∩ space M)"
by auto
also have "… ∈ sets M"
by (intro sets.Diff sets.top sets.Un sets.countable_UN) (auto intro!: fin)
finally show ?thesis .
qed

lemma measurable_THE:
fixes P :: "'a ⇒ 'b ⇒ bool"
assumes [measurable]: "⋀i. Measurable.pred M (P i)"
assumes I[simp]: "countable I" "⋀i x. x ∈ space M ⟹ P i x ⟹ i ∈ I"
assumes unique: "⋀x i j. x ∈ space M ⟹ P i x ⟹ P j x ⟹ i = j"
shows "(λx. THE i. P i x) ∈ measurable M (count_space UNIV)"
unfolding measurable_def
proof safe
fix X
define f where "f x = (THE i. P i x)" for x
define undef where "undef = (THE i::'a. False)"
{ fix i x assume "x ∈ space M" "P i x" then have "f x = i"
unfolding f_def using unique by auto }
note f_eq = this
{ fix x assume "x ∈ space M" "∀i∈I. ¬ P i x"
then have "⋀i. ¬ P i x"
using I(2)[of x] by auto
then have "f x = undef"
by (auto simp: undef_def f_def) }
then have "f -` X ∩ space M = (⋃i∈I ∩ X. {x∈space M. P i x}) ∪
(if undef ∈ X then space M - (⋃i∈I. {x∈space M. P i x}) else {})"
by (auto dest: f_eq)
also have "… ∈ sets M"
by (auto intro!: sets.Diff sets.countable_UN')
finally show "f -` X ∩ space M ∈ sets M" .
qed simp

lemma measurable_Ex1[measurable (raw)]:
assumes [simp]: "countable I" and [measurable]: "⋀i. i ∈ I ⟹ Measurable.pred M (P i)"
shows "Measurable.pred M (λx. ∃!i∈I. P i x)"
unfolding bex1_def by measurable

lemma measurable_Sup_nat[measurable (raw)]:
fixes F :: "'a ⇒ nat set"
assumes [measurable]: "⋀i. Measurable.pred M (λx. i ∈ F x)"
shows "(λx. Sup (F x)) ∈ M →⇩M count_space UNIV"
fix a
have F_empty_iff: "F x = {} ⟷ (∀i. i ∉ F x)" for x
by auto
have "Measurable.pred M (λx. if finite (F x) then if F x = {} then a = 0
else a ∈ F x ∧ (∀j. j ∈ F x ⟶ j ≤ a) else a = the None)"
unfolding finite_nat_set_iff_bounded Ball_def F_empty_iff by measurable
moreover have "(λx. Sup (F x)) -` {a} ∩ space M =
{x∈space M. if finite (F x) then if F x = {} then a = 0
else a ∈ F x ∧ (∀j. j ∈ F x ⟶ j ≤ a) else a = the None}"
by (intro set_eqI)
(auto simp: Sup_nat_def Max.infinite intro!: Max_in Max_eqI)
ultimately show "(λx. Sup (F x)) -` {a} ∩ space M ∈ sets M"
by auto
qed

lemma measurable_if_split[measurable (raw)]:
"(c ⟹ Measurable.pred M f) ⟹ (¬ c ⟹ Measurable.pred M g) ⟹
Measurable.pred M (if c then f else g)"
by simp

lemma pred_restrict_space:
assumes "S ∈ sets M"
shows "Measurable.pred (restrict_space M S) P ⟷ Measurable.pred M (λx. x ∈ S ∧ P x)"
unfolding pred_def sets_Collect_restrict_space_iff[OF assms] ..

lemma measurable_predpow[measurable]:
assumes "Measurable.pred M T"
assumes "⋀Q. Measurable.pred M Q ⟹ Measurable.pred M (R Q)"
shows "Measurable.pred M ((R ^^ n) T)"
by (induct n) (auto intro: assms)

lemma measurable_compose_countable_restrict:
assumes P: "countable {i. P i}"
and f: "f ∈ M →⇩M count_space UNIV"
and Q: "⋀i. P i ⟹ pred M (Q i)"
shows "pred M (λx. P (f x) ∧ Q (f x) x)"
proof -
have P_f: "{x ∈ space M. P (f x)} ∈ sets M"
unfolding pred_def[symmetric] by (rule measurable_compose[OF f]) simp
have "pred (restrict_space M {x∈space M. P (f x)}) (λx. Q (f x) x)"
proof (rule measurable_compose_countable'[where g=f, OF _ _ P])
show "f ∈ restrict_space M {x∈space M. P (f x)} →⇩M count_space {i. P i}"
by (rule measurable_count_space_extend[OF subset_UNIV])
(auto simp: space_restrict_space intro!: measurable_restrict_space1 f)
qed (auto intro!: measurable_restrict_space1 Q)
then show ?thesis
unfolding pred_restrict_space[OF P_f] by (simp cong: measurable_cong)
qed

lemma measurable_limsup [measurable (raw)]:
assumes [measurable]: "⋀n. A n ∈ sets M"
shows "limsup A ∈ sets M"
by (subst limsup_INF_SUP, auto)

lemma measurable_liminf [measurable (raw)]:
assumes [measurable]: "⋀n. A n ∈ sets M"
shows "liminf A ∈ sets M"
by (subst liminf_SUP_INF, auto)

lemma measurable_case_enat[measurable (raw)]:
assumes f: "f ∈ M →⇩M count_space UNIV" and g: "⋀i. g i ∈ M →⇩M N" and h: "h ∈ M →⇩M N"
shows "(λx. case f x of enat i ⇒ g i x | ∞ ⇒ h x) ∈ M →⇩M N"
apply (rule measurable_compose_countable[OF _ f])
subgoal for i
by (cases i) (auto intro: g h)
done

hide_const (open) pred

end

```