src/HOL/Probability/Probability_Mass_Function.thy
changeset 59325 922d31f5c3f5
parent 59134 a71f2e256ee2
child 59327 8a779359df67
     1.1 --- a/src/HOL/Probability/Probability_Mass_Function.thy	Wed Jan 07 18:09:11 2015 +0100
     1.2 +++ b/src/HOL/Probability/Probability_Mass_Function.thy	Fri Jan 09 09:16:51 2015 +0100
     1.3 @@ -1041,11 +1041,19 @@
     1.4      let ?P = "\<lambda>y. to_nat_on (A y)"
     1.5      def pp \<equiv> "map_pmf (\<lambda>(x, y). (y, ?P y x)) pq"
     1.6      let ?pp = "\<lambda>y x. pmf pp (y, x)"
     1.7 -    { fix x y have "x \<in> A y \<Longrightarrow> pmf pp (y, ?P y x) = pmf pq (x, y)"
     1.8 +    { fix x y have "x \<in> A y \<Longrightarrow> ?pp y (?P y x) = pmf pq (x, y)"
     1.9          unfolding pp_def
    1.10          by (intro pmf_map_inj[of "\<lambda>(x, y). (y, ?P y x)" pq "(x, y)", simplified])
    1.11             (auto simp: inj_on_def A) }
    1.12      note pmf_pp = this
    1.13 +    have pp_0: "\<And>y x. pmf q y = 0 \<Longrightarrow> ?pp y x = 0"
    1.14 +    proof(erule contrapos_pp)
    1.15 +      fix y x
    1.16 +      assume "?pp y x \<noteq> 0"
    1.17 +      hence "(y, x) \<in> set_pmf pp" by(simp add: set_pmf_iff)
    1.18 +      hence "y \<in> set_pmf q" by(auto simp add: pp_def q set_map_pmf intro: rev_image_eqI)
    1.19 +      thus "pmf q y \<noteq> 0" by(simp add: set_pmf_iff)
    1.20 +    qed
    1.21  
    1.22      def B \<equiv> "\<lambda>y. {z. (y, z) \<in> set_pmf qr}"
    1.23      then have "\<And>y. B y \<subseteq> set_pmf r" by (auto simp add: r set_map_pmf intro: rev_image_eqI)
    1.24 @@ -1056,318 +1064,50 @@
    1.25      let ?R = "\<lambda>y. to_nat_on (B y)"
    1.26      def rr \<equiv> "map_pmf (\<lambda>(y, z). (y, ?R y z)) qr"
    1.27      let ?rr = "\<lambda>y z. pmf rr (y, z)"
    1.28 -    { fix y z have "z \<in> B y \<Longrightarrow> pmf rr (y, ?R y z) = pmf qr (y, z)"
    1.29 +    { fix y z have "z \<in> B y \<Longrightarrow> ?rr y (?R y z) = pmf qr (y, z)"
    1.30          unfolding rr_def
    1.31          by (intro pmf_map_inj[of "\<lambda>(y, z). (y, ?R y z)" qr "(y, z)", simplified])
    1.32             (auto simp: inj_on_def B) }
    1.33      note pmf_rr = this
    1.34 -
    1.35 -    have eq: "\<And>y. (\<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV) = (\<integral>\<^sup>+ z. ?rr y z \<partial>count_space UNIV)"
    1.36 -    proof -
    1.37 -      fix y
    1.38 -      have "(\<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV) = pmf q y"
    1.39 -        by (simp add: nn_integral_pmf' inj_on_def pp_def q)
    1.40 -           (auto simp add: ereal_pmf_map intro!: arg_cong2[where f=emeasure])
    1.41 -      also have "\<dots> = (\<integral>\<^sup>+ x. ?rr y x \<partial>count_space UNIV)"
    1.42 -        by (simp add: nn_integral_pmf' inj_on_def rr_def q')
    1.43 -           (auto simp add: ereal_pmf_map intro!: arg_cong2[where f=emeasure])
    1.44 -      finally show "?thesis y" .
    1.45 +    have rr_0: "\<And>y z. pmf q y = 0 \<Longrightarrow> ?rr y z = 0"
    1.46 +    proof(erule contrapos_pp)
    1.47 +      fix y z
    1.48 +      assume "?rr y z \<noteq> 0"
    1.49 +      hence "(y, z) \<in> set_pmf rr" by(simp add: set_pmf_iff)
    1.50 +      hence "y \<in> set_pmf q" by(auto simp add: rr_def q' set_map_pmf intro: rev_image_eqI)
    1.51 +      thus "pmf q y \<noteq> 0" by(simp add: set_pmf_iff)
    1.52      qed
    1.53  
    1.54 -    def assign_aux \<equiv> "\<lambda>y remainder start weight z.
    1.55 -       if z < start then 0
    1.56 -       else if z = start then min weight remainder
    1.57 -       else if remainder + setsum (?rr y) {Suc start ..<z} < weight then min (weight - remainder - setsum (?rr y) {Suc start..<z}) (?rr y z) else 0"
    1.58 -    hence assign_aux_alt_def: "\<And>y remainder start weight z. assign_aux y remainder start weight z = 
    1.59 -       (if z < start then 0
    1.60 -        else if z = start then min weight remainder
    1.61 -        else if remainder + setsum (?rr y) {Suc start ..<z} < weight then min (weight - remainder - setsum (?rr y) {Suc start..<z}) (?rr y z) else 0)"
    1.62 -       by simp
    1.63 -    { fix y and remainder :: real and start and weight :: real
    1.64 -      assume weight_nonneg: "0 \<le> weight"
    1.65 -      let ?assign_aux = "assign_aux y remainder start weight"
    1.66 -      { fix z
    1.67 -        have "setsum ?assign_aux {..<z} =
    1.68 -           (if z \<le> start then 0 else if remainder + setsum (?rr y) {Suc start..<z} < weight then remainder + setsum (?rr y) {Suc start..<z} else weight)"
    1.69 -        proof(induction z)
    1.70 -          case (Suc z) show ?case
    1.71 -            by (auto simp add: Suc.IH assign_aux_alt_def[where z=z] not_less)
    1.72 -               (metis add.commute add.left_commute add_increasing pmf_nonneg)
    1.73 -        qed(auto simp add: assign_aux_def) }
    1.74 -      note setsum_start_assign_aux = this
    1.75 -      moreover {
    1.76 -        assume remainder_nonneg: "0 \<le> remainder"
    1.77 -        have [simp]: "\<And>z. 0 \<le> ?assign_aux z"
    1.78 -          by(simp add: assign_aux_def weight_nonneg remainder_nonneg)
    1.79 -        moreover have "\<And>z. \<lbrakk> ?rr y z = 0; remainder \<le> ?rr y start \<rbrakk> \<Longrightarrow> ?assign_aux z = 0"
    1.80 -          using remainder_nonneg weight_nonneg
    1.81 -          by(auto simp add: assign_aux_def min_def)
    1.82 -        moreover have "(\<integral>\<^sup>+ z. ?assign_aux z \<partial>count_space UNIV) = 
    1.83 -          min weight (\<integral>\<^sup>+ z. (if z < start then 0 else if z = start then remainder else ?rr y z) \<partial>count_space UNIV)"
    1.84 -          (is "?lhs = ?rhs" is "_ = min _ (\<integral>\<^sup>+ y. ?f y \<partial>_)")
    1.85 -        proof -
    1.86 -          have "?lhs = (SUP n. \<Sum>z<n. ereal (?assign_aux z))"
    1.87 -            by(simp add: nn_integral_count_space_nat suminf_ereal_eq_SUP)
    1.88 -          also have "\<dots> = (SUP n. min weight (\<Sum>z<n. ?f z))"
    1.89 -          proof(rule arg_cong2[where f=SUPREMUM] ext refl)+
    1.90 -            fix n
    1.91 -            have "(\<Sum>z<n. ereal (?assign_aux z)) = min weight ((if n > start then remainder else 0) + setsum ?f {Suc start..<n})"
    1.92 -              using weight_nonneg remainder_nonneg by(simp add: setsum_start_assign_aux min_def)
    1.93 -            also have "\<dots> = min weight (setsum ?f {start..<n})"
    1.94 -              by(simp add: setsum_head_upt_Suc)
    1.95 -            also have "\<dots> = min weight (setsum ?f {..<n})"
    1.96 -              by(intro arg_cong2[where f=min] setsum.mono_neutral_left) auto
    1.97 -            finally show "(\<Sum>z<n. ereal (?assign_aux z)) = \<dots>" .
    1.98 -          qed
    1.99 -          also have "\<dots> = min weight (SUP n. setsum ?f {..<n})"
   1.100 -            unfolding inf_min[symmetric] by(subst inf_SUP) simp
   1.101 -          also have "\<dots> = ?rhs"
   1.102 -            by(simp add: nn_integral_count_space_nat suminf_ereal_eq_SUP remainder_nonneg)
   1.103 -          finally show ?thesis .
   1.104 -        qed
   1.105 -        moreover note calculation }
   1.106 -      moreover note calculation }
   1.107 -    note setsum_start_assign_aux = this(1)
   1.108 -      and assign_aux_nonneg [simp] = this(2)
   1.109 -      and assign_aux_eq_0_outside = this(3)
   1.110 -      and nn_integral_assign_aux = this(4)
   1.111 -    { fix y and remainder :: real and start target
   1.112 -      have "setsum (?rr y) {Suc start..<target} \<ge> 0" by (simp add: setsum_nonneg)
   1.113 -      moreover assume "0 \<le> remainder"
   1.114 -      ultimately have "assign_aux y remainder start 0 target = 0"
   1.115 -        by(auto simp add: assign_aux_def min_def) }
   1.116 -    note assign_aux_weight_0 [simp] = this
   1.117 +    have nn_integral_pp2: "\<And>y. (\<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV) = pmf q y"
   1.118 +      by (simp add: nn_integral_pmf' inj_on_def pp_def q)
   1.119 +         (auto simp add: ereal_pmf_map intro!: arg_cong2[where f=emeasure])
   1.120 +    have nn_integral_rr1: "\<And>y. (\<integral>\<^sup>+ x. ?rr y x \<partial>count_space UNIV) = pmf q y"
   1.121 +      by (simp add: nn_integral_pmf' inj_on_def rr_def q')
   1.122 +         (auto simp add: ereal_pmf_map intro!: arg_cong2[where f=emeasure])
   1.123 +    have eq: "\<And>y. (\<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV) = (\<integral>\<^sup>+ z. ?rr y z \<partial>count_space UNIV)"
   1.124 +      by(simp add: nn_integral_pp2 nn_integral_rr1)
   1.125  
   1.126 -    def find_start \<equiv> "\<lambda>y weight. if \<exists>n. weight \<le> setsum (?rr y)  {..n} then Some (LEAST n. weight \<le> setsum (?rr y) {..n}) else None"
   1.127 -    have find_start_eq_Some_above:
   1.128 -      "\<And>y weight n. find_start y weight = Some n \<Longrightarrow> weight \<le> setsum (?rr y) {..n}"
   1.129 -      by(drule sym)(auto simp add: find_start_def split: split_if_asm intro: LeastI)
   1.130 -    { fix y weight n
   1.131 -      assume find_start: "find_start y weight = Some n"
   1.132 -      and weight: "0 \<le> weight"
   1.133 -      have "setsum (?rr y) {..n} \<le> ?rr y n + weight"
   1.134 -      proof(rule ccontr)
   1.135 -        assume "\<not> ?thesis"
   1.136 -        hence "?rr y n + weight < setsum (?rr y) {..n}" by simp
   1.137 -        moreover with weight obtain n' where "n = Suc n'" by(cases n) auto
   1.138 -        ultimately have "weight \<le> setsum (?rr y) {..n'}" by simp
   1.139 -        hence "(LEAST n. weight \<le> setsum (?rr y) {..n}) \<le> n'" by(rule Least_le)
   1.140 -        moreover from find_start have "n = (LEAST n. weight \<le> setsum (?rr y) {..n})"
   1.141 -          by(auto simp add: find_start_def split: split_if_asm)
   1.142 -        ultimately show False using \<open>n = Suc n'\<close> by auto
   1.143 -      qed }
   1.144 -    note find_start_eq_Some_least = this
   1.145 -    have find_start_0 [simp]: "\<And>y. find_start y 0 = Some 0"
   1.146 -      by(auto simp add: find_start_def intro!: exI[where x=0])
   1.147 -    { fix y and weight :: real
   1.148 -      assume "weight < \<integral>\<^sup>+ z. ?rr y z \<partial>count_space UNIV"
   1.149 -      also have "(\<integral>\<^sup>+ z. ?rr y z \<partial>count_space UNIV) = (SUP n. \<Sum>z<n. ereal (?rr y z))"
   1.150 -        by(simp add: nn_integral_count_space_nat suminf_ereal_eq_SUP)
   1.151 -      finally obtain n where "weight < (\<Sum>z<n. ?rr y z)" by(auto simp add: less_SUP_iff)
   1.152 -      hence "weight \<in> dom (find_start y)"
   1.153 -        by(auto simp add: find_start_def)(meson atMost_iff finite_atMost lessThan_iff less_imp_le order_trans pmf_nonneg setsum_mono3 subsetI) }
   1.154 -    note in_dom_find_startI = this
   1.155 -    { fix y and w w' :: real and m
   1.156 -      let ?m' = "LEAST m. w' \<le> setsum (?rr y) {..m}"
   1.157 -      assume "w' \<le> w"
   1.158 -      also  assume "find_start y w = Some m"
   1.159 -      hence "w \<le> setsum (?rr y) {..m}" by(rule find_start_eq_Some_above)
   1.160 -      finally have "find_start y w' = Some ?m'" by(auto simp add: find_start_def)
   1.161 -      moreover from \<open>w' \<le> setsum (?rr y) {..m}\<close> have "?m' \<le> m" by(rule Least_le)
   1.162 -      ultimately have "\<exists>m'. find_start y w' = Some m' \<and> m' \<le> m" by blast }
   1.163 -    note find_start_mono = this[rotated]
   1.164 -
   1.165 -    def assign \<equiv> "\<lambda>y x z. let used = setsum (?pp y) {..<x}
   1.166 -      in case find_start y used of None \<Rightarrow> 0
   1.167 -         | Some start \<Rightarrow> assign_aux y (setsum (?rr y) {..start} - used) start (?pp y x) z"
   1.168 -    hence assign_alt_def: "\<And>y x z. assign y x z = 
   1.169 -      (let used = setsum (?pp y) {..<x}
   1.170 -       in case find_start y used of None \<Rightarrow> 0
   1.171 -          | Some start \<Rightarrow> assign_aux y (setsum (?rr y) {..start} - used) start (?pp y x) z)"
   1.172 -      by simp
   1.173 -    have assign_nonneg [simp]: "\<And>y x z. 0 \<le> assign y x z"
   1.174 -      by(simp add: assign_def diff_le_iff find_start_eq_Some_above Let_def split: option.split)
   1.175 +    def assign \<equiv> "\<lambda>y x z. ?pp y x * ?rr y z / pmf q y"
   1.176 +    have assign_nonneg [simp]: "\<And>y x z. 0 \<le> assign y x z" by(simp add: assign_def)
   1.177      have assign_eq_0_outside: "\<And>y x z. \<lbrakk> ?pp y x = 0 \<or> ?rr y z = 0 \<rbrakk> \<Longrightarrow> assign y x z = 0"
   1.178 -      by(auto simp add: assign_def assign_aux_eq_0_outside diff_le_iff find_start_eq_Some_above find_start_eq_Some_least setsum_nonneg Let_def split: option.split)
   1.179 -
   1.180 -    { fix y x z
   1.181 -      have "(\<Sum>n<Suc x. assign y n z) =
   1.182 -            (case find_start y (setsum (?pp y) {..<x}) of None \<Rightarrow> ?rr y z
   1.183 -             | Some m \<Rightarrow> if z < m then ?rr y z 
   1.184 -                         else min (?rr y z) (max 0 (setsum (?pp y) {..<x} + ?pp y x - setsum (?rr y) {..<z})))"
   1.185 -        (is "?lhs x = ?rhs x")
   1.186 -      proof(induction x)
   1.187 -        case 0 thus ?case 
   1.188 -          by(auto simp add: assign_def assign_aux_def setsum_head_upt_Suc atLeast0LessThan[symmetric] not_less field_simps max_def)
   1.189 -      next
   1.190 -        case (Suc x)
   1.191 -        have "?lhs (Suc x) = ?lhs x + assign y (Suc x) z" by simp
   1.192 -        also have "?lhs x = ?rhs x" by(rule Suc.IH)
   1.193 -        also have "?rhs x + assign y (Suc x) z = ?rhs (Suc x)"
   1.194 -        proof(cases "find_start y (setsum (?pp y) {..<Suc x})")
   1.195 -          case None
   1.196 -          thus ?thesis
   1.197 -            by(auto split: option.split simp add: assign_def min_def max_def diff_le_iff setsum_nonneg not_le field_simps)
   1.198 -              (metis add.commute add_increasing find_start_def lessThan_Suc_atMost less_imp_le option.distinct(1) setsum_lessThan_Suc)+
   1.199 -        next 
   1.200 -          case (Some m)
   1.201 -          have [simp]: "setsum (?rr y) {..m} = ?rr y m + setsum (?rr y) {..<m}"
   1.202 -            by(simp add: ivl_disj_un(2)[symmetric])
   1.203 -          from Some obtain m' where m': "find_start y (setsum (?pp y) {..<x}) = Some m'" "m' \<le> m"
   1.204 -            by(auto dest: find_start_mono[where w'2="setsum (?pp y) {..<x}"])
   1.205 -          moreover {
   1.206 -            assume "z < m"
   1.207 -            then have "setsum (?rr y) {..z} \<le> setsum (?rr y) {..<m}"
   1.208 -              by(auto intro: setsum_mono3)
   1.209 -            also have "\<dots> \<le> setsum (?pp y) {..<Suc x}" using find_start_eq_Some_least[OF Some]
   1.210 -              by(simp add: ivl_disj_un(2)[symmetric] setsum_nonneg)
   1.211 -            finally have "?rr y z \<le> max 0 (setsum (?pp y) {..<x} + ?pp y x - setsum (?rr y) {..<z})"
   1.212 -              by(auto simp add: ivl_disj_un(2)[symmetric] max_def diff_le_iff simp del: pmf_le_0_iff)
   1.213 -          } moreover {
   1.214 -            assume "m \<le> z"
   1.215 -            have "setsum (?pp y) {..<Suc x} \<le> setsum (?rr y) {..m}"
   1.216 -              using Some by(rule find_start_eq_Some_above)
   1.217 -            also have "\<dots> \<le> setsum (?rr y) {..<Suc z}" using \<open>m \<le> z\<close> by(intro setsum_mono3) auto
   1.218 -            finally have "max 0 (setsum (?pp y) {..<x} + ?pp y x - setsum (?rr y) {..<z}) \<le> ?rr y z" by simp
   1.219 -            moreover have "z \<noteq> m \<Longrightarrow> setsum (?rr y) {..m} + setsum (?rr y) {Suc m..<z} = setsum (?rr y) {..<z}"
   1.220 -              using \<open>m \<le> z\<close>
   1.221 -              by(subst ivl_disj_un(8)[where l="Suc m", symmetric])
   1.222 -                (simp_all add: setsum_Un ivl_disj_un(2)[symmetric] setsum.neutral)
   1.223 -            moreover note calculation
   1.224 -          } moreover {
   1.225 -            assume "m < z"
   1.226 -            have "setsum (?pp y) {..<Suc x} \<le> setsum (?rr y) {..m}"
   1.227 -              using Some by(rule find_start_eq_Some_above)
   1.228 -            also have "\<dots> \<le> setsum (?rr y) {..<z}" using \<open>m < z\<close> by(intro setsum_mono3) auto
   1.229 -            finally have "max 0 (setsum (?pp y) {..<Suc x} - setsum (?rr y) {..<z}) = 0" by simp }
   1.230 -          moreover have "setsum (?pp y) {..<Suc x} \<ge> setsum (?rr y) {..<m}"
   1.231 -            using find_start_eq_Some_least[OF Some]
   1.232 -            by(simp add: setsum_nonneg ivl_disj_un(2)[symmetric])
   1.233 -          moreover hence "setsum (?pp y) {..<Suc (Suc x)} \<ge> setsum (?rr y) {..<m}"
   1.234 -            by(fastforce intro: order_trans)
   1.235 -          ultimately show ?thesis using Some
   1.236 -            by(auto simp add: assign_def assign_aux_def Let_def field_simps max_def)
   1.237 -        qed
   1.238 -        finally show ?case .
   1.239 -      qed }
   1.240 -    note setsum_assign = this
   1.241 -
   1.242 +      by(auto simp add: assign_def)
   1.243      have nn_integral_assign1: "\<And>y z. (\<integral>\<^sup>+ x. assign y x z \<partial>count_space UNIV) = ?rr y z"
   1.244      proof -
   1.245        fix y z
   1.246 -      have "(\<integral>\<^sup>+ x. assign y x z \<partial>count_space UNIV) = (SUP n. ereal (\<Sum>x<n. assign y x z))"
   1.247 -        by(simp add: nn_integral_count_space_nat suminf_ereal_eq_SUP)
   1.248 -      also have "\<dots> = ?rr y z"
   1.249 -      proof(rule antisym)
   1.250 -        show "(SUP n. ereal (\<Sum>x<n. assign y x z)) \<le> ?rr y z"
   1.251 -        proof(rule SUP_least)
   1.252 -          fix n
   1.253 -          show "ereal (\<Sum>x<n. (assign y x z)) \<le> ?rr y z"
   1.254 -            using setsum_assign[of y z "n - 1"]
   1.255 -            by(cases n)(simp_all split: option.split)
   1.256 -        qed
   1.257 -        show "?rr y z \<le> (SUP n. ereal (\<Sum>x<n. assign y x z))"
   1.258 -        proof(cases "setsum (?rr y) {..z} < \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV")
   1.259 -          case True
   1.260 -          then obtain n where "setsum (?rr y) {..z} < setsum (?pp y) {..<n}"
   1.261 -            by(auto simp add: nn_integral_count_space_nat suminf_ereal_eq_SUP less_SUP_iff)
   1.262 -          moreover have "\<And>k. k < z \<Longrightarrow> setsum (?rr y) {..k} \<le> setsum (?rr y) {..<z}"
   1.263 -            by(auto intro: setsum_mono3)
   1.264 -          ultimately have "?rr y z \<le> (\<Sum>x<Suc n. assign y x z)"
   1.265 -            by(subst setsum_assign)(auto split: option.split dest!: find_start_eq_Some_above simp add: ivl_disj_un(2)[symmetric] add.commute add_increasing le_diff_eq le_max_iff_disj)
   1.266 -          also have "\<dots> \<le> (SUP n. ereal (\<Sum>x<n. assign y x z))" 
   1.267 -            by(rule SUP_upper) simp
   1.268 -          finally show ?thesis by simp
   1.269 -        next
   1.270 -          case False
   1.271 -          have "setsum (?rr y) {..z} = \<integral>\<^sup>+ z. ?rr y z \<partial>count_space {..z}"
   1.272 -            by(simp add: nn_integral_count_space_finite max_def)
   1.273 -          also have "\<dots> \<le> \<integral>\<^sup>+ z. ?rr y z \<partial>count_space UNIV"
   1.274 -            by(auto simp add: nn_integral_count_space_indicator indicator_def intro: nn_integral_mono)
   1.275 -          also have "\<dots> = \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV" by(simp add: eq)
   1.276 -          finally have *: "setsum (?rr y) {..z} = \<dots>" using False by simp
   1.277 -          also have "\<dots> = (SUP n. ereal (\<Sum>x<n. ?pp y x))"
   1.278 -            by(simp add: nn_integral_count_space_nat suminf_ereal_eq_SUP)
   1.279 -          also have "\<dots> \<le> (SUP n. ereal (\<Sum>x<n. assign y x z)) + setsum (?rr y) {..<z}"
   1.280 -          proof(rule SUP_least)
   1.281 -            fix n
   1.282 -            have "setsum (?pp y) {..<n} = \<integral>\<^sup>+ x. ?pp y x \<partial>count_space {..<n}"
   1.283 -              by(simp add: nn_integral_count_space_finite max_def)
   1.284 -            also have "\<dots> \<le> \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV"
   1.285 -              by(auto simp add: nn_integral_count_space_indicator indicator_def intro: nn_integral_mono)
   1.286 -            also have "\<dots> = setsum (?rr y) {..z}" using * by simp
   1.287 -            finally obtain k where k: "find_start y (setsum (?pp y) {..<n}) = Some k"
   1.288 -              by(fastforce simp add: find_start_def)
   1.289 -            with \<open>ereal (setsum (?pp y) {..<n}) \<le> setsum (?rr y) {..z}\<close>
   1.290 -            have "k \<le> z" by(auto simp add: find_start_def split: split_if_asm intro: Least_le)
   1.291 -            then have "setsum (?pp y) {..<n} - setsum (?rr y) {..<z} \<le> ereal (\<Sum>x<Suc n. assign y x z)"
   1.292 -              using \<open>ereal (setsum (?pp y) {..<n}) \<le> setsum (?rr y) {..z}\<close>
   1.293 -              apply (subst setsum_assign)
   1.294 -              apply (auto simp add: field_simps max_def k ivl_disj_un(2)[symmetric])
   1.295 -              apply (meson add_increasing le_cases pmf_nonneg)
   1.296 -              done
   1.297 -            also have "\<dots> \<le> (SUP n. ereal (\<Sum>x<n. assign y x z))"
   1.298 -              by(rule SUP_upper) simp
   1.299 -            finally show "ereal (\<Sum>x<n. ?pp y x) \<le> \<dots> + setsum (?rr y) {..<z}" 
   1.300 -              by(simp add: ereal_minus(1)[symmetric] ereal_minus_le del: ereal_minus(1))
   1.301 -          qed
   1.302 -          finally show ?thesis
   1.303 -            by(simp add: ivl_disj_un(2)[symmetric] plus_ereal.simps(1)[symmetric] ereal_add_le_add_iff2 del: plus_ereal.simps(1))
   1.304 -        qed
   1.305 -      qed
   1.306 +      have "(\<integral>\<^sup>+ x. assign y x z \<partial>count_space UNIV) = 
   1.307 +            (\<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV) * (?rr y z / pmf q y)"
   1.308 +        by(simp add: assign_def nn_integral_multc times_ereal.simps(1)[symmetric] divide_real_def mult.assoc del: times_ereal.simps(1))
   1.309 +      also have "\<dots> = ?rr y z" by(simp add: rr_0 nn_integral_pp2)
   1.310        finally show "?thesis y z" .
   1.311      qed
   1.312 -
   1.313 -    { fix y x
   1.314 -      have "(\<integral>\<^sup>+ z. assign y x z \<partial>count_space UNIV) = ?pp y x"
   1.315 -      proof(cases "setsum (?pp y) {..<x} = \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV")
   1.316 -        case False
   1.317 -        let ?used = "setsum (?pp y) {..<x}"
   1.318 -        have "?used = \<integral>\<^sup>+ x. ?pp y x \<partial>count_space {..<x}"
   1.319 -          by(simp add: nn_integral_count_space_finite max_def)
   1.320 -        also have "\<dots> \<le> \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV"
   1.321 -          by(auto simp add: nn_integral_count_space_indicator indicator_def intro!: nn_integral_mono)
   1.322 -        finally have "?used < \<dots>" using False by auto
   1.323 -        also note eq finally have "?used \<in> dom (find_start y)" by(rule in_dom_find_startI)
   1.324 -        then obtain k where k: "find_start y ?used = Some k" by auto
   1.325 -        let ?f = "\<lambda>z. if z < k then 0 else if z = k then setsum (?rr y) {..k} - ?used else ?rr y z"
   1.326 -        let ?g = "\<lambda>x'. if x' < x then 0 else ?pp y x'"
   1.327 -        have "?pp y x = ?g x" by simp
   1.328 -        also have "?g x \<le> \<integral>\<^sup>+ x'. ?g x' \<partial>count_space UNIV" by(rule nn_integral_ge_point) simp
   1.329 -        also {
   1.330 -          have "?used = \<integral>\<^sup>+ x. ?pp y x \<partial>count_space {..<x}"
   1.331 -            by(simp add: nn_integral_count_space_finite max_def)
   1.332 -          also have "\<dots> = \<integral>\<^sup>+ x'. (if x' < x then ?pp y x' else 0) \<partial>count_space UNIV"
   1.333 -            by(simp add: nn_integral_count_space_indicator indicator_def if_distrib zero_ereal_def cong del: if_cong)
   1.334 -          also have "(\<integral>\<^sup>+ x'. ?g x' \<partial>count_space UNIV) + \<dots> = \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV"
   1.335 -            by(subst nn_integral_add[symmetric])(auto intro: nn_integral_cong)
   1.336 -          also note calculation }
   1.337 -        ultimately have "ereal (?pp y x) + ?used \<le> \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV"
   1.338 -          by (metis (no_types, lifting) ereal_add_mono order_refl)
   1.339 -        also note eq
   1.340 -        also have "(\<integral>\<^sup>+ z. ?rr y z \<partial>count_space UNIV) = (\<integral>\<^sup>+ z. ?f z \<partial>count_space UNIV) + (\<integral>\<^sup>+ z. (if z < k then ?rr y z else if z = k then ?used - setsum (?rr y) {..<k} else 0) \<partial>count_space UNIV)"
   1.341 -          using k by(subst nn_integral_add[symmetric])(auto intro!: nn_integral_cong simp add: ivl_disj_un(2)[symmetric] setsum_nonneg dest: find_start_eq_Some_least find_start_eq_Some_above)
   1.342 -        also have "(\<integral>\<^sup>+ z. (if z < k then ?rr y z else if z = k then ?used - setsum (?rr y) {..<k} else 0) \<partial>count_space UNIV) =
   1.343 -          (\<integral>\<^sup>+ z. (if z < k then ?rr y z else if z = k then ?used - setsum (?rr y) {..<k} else 0) \<partial>count_space {..k})"
   1.344 -          by(auto simp add: nn_integral_count_space_indicator indicator_def intro: nn_integral_cong)
   1.345 -        also have "\<dots> = ?used" 
   1.346 -          using k by(auto simp add: nn_integral_count_space_finite max_def ivl_disj_un(2)[symmetric] diff_le_iff setsum_nonneg dest: find_start_eq_Some_least)
   1.347 -        finally have "?pp y x \<le> (\<integral>\<^sup>+ z. ?f z \<partial>count_space UNIV)"
   1.348 -          by(cases "\<integral>\<^sup>+ z. ?f z \<partial>count_space UNIV") simp_all
   1.349 -        then show ?thesis using k
   1.350 -          by(simp add: assign_def nn_integral_assign_aux diff_le_iff find_start_eq_Some_above min_def)
   1.351 -      next
   1.352 -        case True
   1.353 -        have "setsum (?pp y) {..x} = \<integral>\<^sup>+ x. ?pp y x \<partial>count_space {..x}"
   1.354 -          by(simp add: nn_integral_count_space_finite max_def)
   1.355 -        also have "\<dots> \<le> \<integral>\<^sup>+ x. ?pp y x \<partial>count_space UNIV"
   1.356 -          by(auto simp add: nn_integral_count_space_indicator indicator_def intro: nn_integral_mono)
   1.357 -        also have "\<dots> = setsum (?pp y) {..<x}" by(simp add: True)
   1.358 -        finally have "?pp y x = 0" by(simp add: ivl_disj_un(2)[symmetric] eq_iff del: pmf_le_0_iff)
   1.359 -        thus ?thesis
   1.360 -          by(cases "find_start y (setsum (?pp y) {..<x})")(simp_all add: assign_def diff_le_iff find_start_eq_Some_above)
   1.361 -      qed }
   1.362 -    note nn_integral_assign2 = this
   1.363 +    have nn_integral_assign2: "\<And>y x. (\<integral>\<^sup>+ z. assign y x z \<partial>count_space UNIV) = ?pp y x"
   1.364 +    proof -
   1.365 +      fix x y
   1.366 +      have "(\<integral>\<^sup>+ z. assign y x z \<partial>count_space UNIV) = (\<integral>\<^sup>+ z. ?rr y z \<partial>count_space UNIV) * (?pp y x / pmf q y)"
   1.367 +        by(simp add: assign_def divide_real_def mult.commute[where a="?pp y x"] mult.assoc nn_integral_multc times_ereal.simps(1)[symmetric] del: times_ereal.simps(1))
   1.368 +      also have "\<dots> = ?pp y x" by(simp add: nn_integral_rr1 pp_0)
   1.369 +      finally show "?thesis y x" .
   1.370 +    qed
   1.371  
   1.372      def a \<equiv> "embed_pmf (\<lambda>(y, x, z). assign y x z)"
   1.373      { fix y x z