1785 by(rule rel_funI) simp |
1785 by(rule rel_funI) simp |
1786 |
1786 |
1787 end |
1787 end |
1788 |
1788 |
1789 |
1789 |
|
1790 primrec replicate_pmf :: "nat \<Rightarrow> 'a pmf \<Rightarrow> 'a list pmf" where |
|
1791 "replicate_pmf 0 _ = return_pmf []" |
|
1792 | "replicate_pmf (Suc n) p = do {x \<leftarrow> p; xs \<leftarrow> replicate_pmf n p; return_pmf (x#xs)}" |
|
1793 |
|
1794 lemma replicate_pmf_1: "replicate_pmf 1 p = map_pmf (\<lambda>x. [x]) p" |
|
1795 by (simp add: map_pmf_def bind_return_pmf) |
|
1796 |
|
1797 lemma set_replicate_pmf: |
|
1798 "set_pmf (replicate_pmf n p) = {xs\<in>lists (set_pmf p). length xs = n}" |
|
1799 by (induction n) (auto simp: length_Suc_conv) |
|
1800 |
|
1801 lemma replicate_pmf_distrib: |
|
1802 "replicate_pmf (m + n) p = |
|
1803 do {xs \<leftarrow> replicate_pmf m p; ys \<leftarrow> replicate_pmf n p; return_pmf (xs @ ys)}" |
|
1804 by (induction m) (simp_all add: bind_return_pmf bind_return_pmf' bind_assoc_pmf) |
|
1805 |
|
1806 lemma power_diff': |
|
1807 assumes "b \<le> a" |
|
1808 shows "x ^ (a - b) = (if x = 0 \<and> a = b then 1 else x ^ a / (x::'a::field) ^ b)" |
|
1809 proof (cases "x = 0") |
|
1810 case True |
|
1811 with assms show ?thesis by (cases "a - b") simp_all |
|
1812 qed (insert assms, simp_all add: power_diff) |
|
1813 |
|
1814 |
|
1815 lemma binomial_pmf_Suc: |
|
1816 assumes "p \<in> {0..1}" |
|
1817 shows "binomial_pmf (Suc n) p = |
|
1818 do {b \<leftarrow> bernoulli_pmf p; |
|
1819 k \<leftarrow> binomial_pmf n p; |
|
1820 return_pmf ((if b then 1 else 0) + k)}" (is "_ = ?rhs") |
|
1821 proof (intro pmf_eqI) |
|
1822 fix k |
|
1823 have A: "indicator {Suc a} (Suc b) = indicator {a} b" for a b |
|
1824 by (simp add: indicator_def) |
|
1825 show "pmf (binomial_pmf (Suc n) p) k = pmf ?rhs k" |
|
1826 by (cases k; cases "k > n") |
|
1827 (insert assms, auto simp: pmf_bind measure_pmf_single A divide_simps algebra_simps |
|
1828 not_less less_eq_Suc_le [symmetric] power_diff') |
|
1829 qed |
|
1830 |
|
1831 lemma binomial_pmf_0: "p \<in> {0..1} \<Longrightarrow> binomial_pmf 0 p = return_pmf 0" |
|
1832 by (rule pmf_eqI) (simp_all add: indicator_def) |
|
1833 |
|
1834 lemma binomial_pmf_altdef: |
|
1835 assumes "p \<in> {0..1}" |
|
1836 shows "binomial_pmf n p = map_pmf (length \<circ> filter id) (replicate_pmf n (bernoulli_pmf p))" |
|
1837 by (induction n) |
|
1838 (insert assms, auto simp: binomial_pmf_Suc map_pmf_def bind_return_pmf bind_assoc_pmf |
|
1839 bind_return_pmf' binomial_pmf_0 intro!: bind_pmf_cong) |
|
1840 |
|
1841 |
1790 subsection \<open>PMFs from assiciation lists\<close> |
1842 subsection \<open>PMFs from assiciation lists\<close> |
1791 |
1843 |
1792 definition pmf_of_list ::" ('a \<times> real) list \<Rightarrow> 'a pmf" where |
1844 definition pmf_of_list ::" ('a \<times> real) list \<Rightarrow> 'a pmf" where |
1793 "pmf_of_list xs = embed_pmf (\<lambda>x. listsum (map snd (filter (\<lambda>z. fst z = x) xs)))" |
1845 "pmf_of_list xs = embed_pmf (\<lambda>x. listsum (map snd (filter (\<lambda>z. fst z = x) xs)))" |
1794 |
1846 |
1919 assumes "pmf_of_list_wf xs" |
1971 assumes "pmf_of_list_wf xs" |
1920 shows "measure (pmf_of_list xs) A = listsum (map snd (filter (\<lambda>x. fst x \<in> A) xs))" |
1972 shows "measure (pmf_of_list xs) A = listsum (map snd (filter (\<lambda>x. fst x \<in> A) xs))" |
1921 using assms unfolding pmf_of_list_wf_def Sigma_Algebra.measure_def |
1973 using assms unfolding pmf_of_list_wf_def Sigma_Algebra.measure_def |
1922 by (subst emeasure_pmf_of_list [OF assms], subst enn2real_ennreal) (auto intro!: listsum_nonneg) |
1974 by (subst emeasure_pmf_of_list [OF assms], subst enn2real_ennreal) (auto intro!: listsum_nonneg) |
1923 |
1975 |
|
1976 (* TODO Move? *) |
|
1977 lemma listsum_nonneg_eq_zero_iff: |
|
1978 fixes xs :: "'a :: linordered_ab_group_add list" |
|
1979 shows "(\<And>x. x \<in> set xs \<Longrightarrow> x \<ge> 0) \<Longrightarrow> listsum xs = 0 \<longleftrightarrow> set xs \<subseteq> {0}" |
|
1980 proof (induction xs) |
|
1981 case (Cons x xs) |
|
1982 from Cons.prems have "listsum (x#xs) = 0 \<longleftrightarrow> x = 0 \<and> listsum xs = 0" |
|
1983 unfolding listsum_simps by (subst add_nonneg_eq_0_iff) (auto intro: listsum_nonneg) |
|
1984 with Cons.IH Cons.prems show ?case by simp |
|
1985 qed simp_all |
|
1986 |
|
1987 lemma listsum_filter_nonzero: |
|
1988 "listsum (filter (\<lambda>x. x \<noteq> 0) xs) = listsum xs" |
|
1989 by (induction xs) simp_all |
|
1990 (* END MOVE *) |
|
1991 |
|
1992 lemma set_pmf_of_list_eq: |
|
1993 assumes "pmf_of_list_wf xs" "\<And>x. x \<in> snd ` set xs \<Longrightarrow> x > 0" |
|
1994 shows "set_pmf (pmf_of_list xs) = fst ` set xs" |
|
1995 proof |
|
1996 { |
|
1997 fix x assume A: "x \<in> fst ` set xs" and B: "x \<notin> set_pmf (pmf_of_list xs)" |
|
1998 then obtain y where y: "(x, y) \<in> set xs" by auto |
|
1999 from B have "listsum (map snd [z\<leftarrow>xs. fst z = x]) = 0" |
|
2000 by (simp add: pmf_pmf_of_list[OF assms(1)] set_pmf_eq) |
|
2001 moreover from y have "y \<in> snd ` {xa \<in> set xs. fst xa = x}" by force |
|
2002 ultimately have "y = 0" using assms(1) |
|
2003 by (subst (asm) listsum_nonneg_eq_zero_iff) (auto simp: pmf_of_list_wf_def) |
|
2004 with assms(2) y have False by force |
|
2005 } |
|
2006 thus "fst ` set xs \<subseteq> set_pmf (pmf_of_list xs)" by blast |
|
2007 qed (insert set_pmf_of_list[OF assms(1)], simp_all) |
|
2008 |
|
2009 lemma pmf_of_list_remove_zeros: |
|
2010 assumes "pmf_of_list_wf xs" |
|
2011 defines "xs' \<equiv> filter (\<lambda>z. snd z \<noteq> 0) xs" |
|
2012 shows "pmf_of_list_wf xs'" "pmf_of_list xs' = pmf_of_list xs" |
|
2013 proof - |
|
2014 have "map snd [z\<leftarrow>xs . snd z \<noteq> 0] = filter (\<lambda>x. x \<noteq> 0) (map snd xs)" |
|
2015 by (induction xs) simp_all |
|
2016 with assms(1) show wf: "pmf_of_list_wf xs'" |
|
2017 by (auto simp: pmf_of_list_wf_def xs'_def listsum_filter_nonzero) |
|
2018 have "listsum (map snd [z\<leftarrow>xs' . fst z = i]) = listsum (map snd [z\<leftarrow>xs . fst z = i])" for i |
|
2019 unfolding xs'_def by (induction xs) simp_all |
|
2020 with assms(1) wf show "pmf_of_list xs' = pmf_of_list xs" |
|
2021 by (intro pmf_eqI) (simp_all add: pmf_pmf_of_list) |
|
2022 qed |
|
2023 |
1924 end |
2024 end |