src/HOL/Probability/PMF_Impl.thy
author paulson <lp15@cam.ac.uk>
Wed, 25 Mar 2020 12:37:57 +0000
changeset 71591 8e4d542f041b
parent 69064 5840724b1d71
child 72581 de581f98a3a1
permissions -rw-r--r--
updated to more modern style
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
     1
(*  Title:      HOL/Probability/PMF_Impl.thy
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
     2
    Author:     Manuel Eberl, TU München
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
     3
    
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
     4
    An implementation of PMFs using Mappings, which are implemented with association lists
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
     5
    by default. Also includes Quickcheck setup for PMFs.
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
     6
*)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
     7
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
     8
section \<open>Code generation for PMFs\<close>
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
     9
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    10
theory PMF_Impl
66453
cc19f7ca2ed6 session-qualified theory imports: isabelle imports -U -i -d '~~/src/Benchmarks' -a;
wenzelm
parents: 64267
diff changeset
    11
imports Probability_Mass_Function "HOL-Library.AList_Mapping"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    12
begin
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    13
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
    14
subsection \<open>General code generation setup\<close>
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
    15
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    16
definition pmf_of_mapping :: "('a, real) mapping \<Rightarrow> 'a pmf" where
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    17
  "pmf_of_mapping m = embed_pmf (Mapping.lookup_default 0 m)" 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    18
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    19
lemma nn_integral_lookup_default:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    20
  fixes m :: "('a, real) mapping"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    21
  assumes "finite (Mapping.keys m)" "All_mapping m (\<lambda>_ x. x \<ge> 0)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    22
  shows   "nn_integral (count_space UNIV) (\<lambda>k. ennreal (Mapping.lookup_default 0 m k)) = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    23
             ennreal (\<Sum>k\<in>Mapping.keys m. Mapping.lookup_default 0 m k)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    24
proof -
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    25
  have "nn_integral (count_space UNIV) (\<lambda>k. ennreal (Mapping.lookup_default 0 m k)) = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    26
          (\<Sum>x\<in>Mapping.keys m. ennreal (Mapping.lookup_default 0 m x))" using assms
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    27
    by (subst nn_integral_count_space'[of "Mapping.keys m"])
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    28
       (auto simp: Mapping.lookup_default_def keys_is_none_rep Option.is_none_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    29
  also from assms have "\<dots> = ennreal (\<Sum>k\<in>Mapping.keys m. Mapping.lookup_default 0 m k)"
64267
b9a1486e79be setsum -> sum
nipkow
parents: 63882
diff changeset
    30
    by (intro sum_ennreal) 
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    31
       (auto simp: Mapping.lookup_default_def All_mapping_def split: option.splits)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    32
  finally show ?thesis .
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    33
qed
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    34
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    35
lemma pmf_of_mapping: 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    36
  assumes "finite (Mapping.keys m)" "All_mapping m (\<lambda>_ p. p \<ge> 0)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    37
  assumes "(\<Sum>x\<in>Mapping.keys m. Mapping.lookup_default 0 m x) = 1"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    38
  shows   "pmf (pmf_of_mapping m) x = Mapping.lookup_default 0 m x"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    39
  unfolding pmf_of_mapping_def
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    40
proof (intro pmf_embed_pmf)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    41
  from assms show "(\<integral>\<^sup>+x. ennreal (Mapping.lookup_default 0 m x) \<partial>count_space UNIV) = 1"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    42
    by (subst nn_integral_lookup_default) (simp_all)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    43
qed (insert assms, simp add: All_mapping_def Mapping.lookup_default_def split: option.splits)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    44
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    45
lemma pmf_of_set_pmf_of_mapping:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    46
  assumes "A \<noteq> {}" "set xs = A" "distinct xs"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    47
  shows   "pmf_of_set A = pmf_of_mapping (Mapping.tabulate xs (\<lambda>_. 1 / real (length xs)))" 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    48
           (is "?lhs = ?rhs")
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    49
  by (rule pmf_eqI, subst pmf_of_mapping)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    50
     (insert assms, auto intro!: All_mapping_tabulate 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    51
                         simp: Mapping.lookup_default_def lookup_tabulate distinct_card)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    52
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    53
lift_definition mapping_of_pmf :: "'a pmf \<Rightarrow> ('a, real) mapping" is
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    54
  "\<lambda>p x. if pmf p x = 0 then None else Some (pmf p x)" .
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    55
  
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    56
lemma lookup_default_mapping_of_pmf: 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    57
  "Mapping.lookup_default 0 (mapping_of_pmf p) x = pmf p x"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    58
  by (simp add: mapping_of_pmf.abs_eq lookup_default_def Mapping.lookup.abs_eq)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    59
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    60
context
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    61
begin
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    62
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    63
interpretation pmf_as_function .
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    64
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    65
lemma nn_integral_pmf_eq_1: "(\<integral>\<^sup>+ x. ennreal (pmf p x) \<partial>count_space UNIV) = 1"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    66
  by transfer simp_all
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    67
end
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    68
  
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    69
lemma pmf_of_mapping_mapping_of_pmf [code abstype]: 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    70
    "pmf_of_mapping (mapping_of_pmf p) = p"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    71
  unfolding pmf_of_mapping_def
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    72
  by (rule pmf_eqI, subst pmf_embed_pmf)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    73
     (insert nn_integral_pmf_eq_1[of p], 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    74
      auto simp: lookup_default_mapping_of_pmf split: option.splits)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    75
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    76
lemma mapping_of_pmfI:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    77
  assumes "\<And>x. x \<in> Mapping.keys m \<Longrightarrow> Mapping.lookup m x = Some (pmf p x)" 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    78
  assumes "Mapping.keys m = set_pmf p"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    79
  shows   "mapping_of_pmf p = m"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    80
  using assms by transfer (rule ext, auto simp: set_pmf_eq)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    81
  
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    82
lemma mapping_of_pmfI':
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    83
  assumes "\<And>x. x \<in> Mapping.keys m \<Longrightarrow> Mapping.lookup_default 0 m x = pmf p x" 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    84
  assumes "Mapping.keys m = set_pmf p"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    85
  shows   "mapping_of_pmf p = m"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    86
  using assms unfolding Mapping.lookup_default_def 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    87
  by transfer (rule ext, force simp: set_pmf_eq)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    88
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    89
lemma return_pmf_code [code abstract]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    90
  "mapping_of_pmf (return_pmf x) = Mapping.update x 1 Mapping.empty"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    91
  by (intro mapping_of_pmfI) (auto simp: lookup_update')
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    92
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    93
lemma pmf_of_set_code_aux:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    94
  assumes "A \<noteq> {}" "set xs = A" "distinct xs"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    95
  shows   "mapping_of_pmf (pmf_of_set A) = Mapping.tabulate xs (\<lambda>_. 1 / real (length xs))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    96
  using assms
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    97
  by (intro mapping_of_pmfI, subst pmf_of_set)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    98
     (auto simp: lookup_tabulate distinct_card)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
    99
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   100
definition pmf_of_set_impl where
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   101
  "pmf_of_set_impl A = mapping_of_pmf (pmf_of_set A)"
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   102
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   103
(* This equation can be used to easily implement pmf_of_set for other set implementations *)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   104
lemma pmf_of_set_impl_code_alt:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   105
  assumes "A \<noteq> {}" "finite A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   106
  shows   "pmf_of_set_impl A = 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   107
             (let p = 1 / real (card A) 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   108
              in  Finite_Set.fold (\<lambda>x. Mapping.update x p) Mapping.empty A)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   109
proof -
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   110
  define p where "p = 1 / real (card A)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   111
  let ?m = "Finite_Set.fold (\<lambda>x. Mapping.update x p) Mapping.empty A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   112
  interpret comp_fun_idem "\<lambda>x. Mapping.update x p"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   113
    by standard (transfer, force simp: fun_eq_iff)+
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   114
  have keys: "Mapping.keys ?m = A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   115
    using assms(2) by (induction A rule: finite_induct) simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   116
  have lookup: "Mapping.lookup ?m x = Some p" if "x \<in> A" for x
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   117
    using assms(2) that by (induction A rule: finite_induct) (auto simp: lookup_update')
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   118
  from keys lookup assms show ?thesis unfolding pmf_of_set_impl_def
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   119
    by (intro mapping_of_pmfI) (simp_all add: Let_def p_def)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   120
qed
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   121
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   122
lemma pmf_of_set_impl_code [code]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   123
  "pmf_of_set_impl (set xs) = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   124
    (if xs = [] then
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   125
         Code.abort (STR ''pmf_of_set of empty set'') (\<lambda>_. mapping_of_pmf (pmf_of_set (set xs)))
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   126
      else let xs' = remdups xs; p = 1 / real (length xs') in
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   127
         Mapping.tabulate xs' (\<lambda>_. p))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   128
  unfolding pmf_of_set_impl_def
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   129
  using pmf_of_set_code_aux[of "set xs" "remdups xs"] by (simp add: Let_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   130
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   131
lemma pmf_of_set_code [code abstract]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   132
  "mapping_of_pmf (pmf_of_set A) = pmf_of_set_impl A"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   133
  by (simp add: pmf_of_set_impl_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   134
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   135
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   136
lemma pmf_of_multiset_pmf_of_mapping:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   137
  assumes "A \<noteq> {#}" "set xs = set_mset A" "distinct xs"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   138
  shows   "mapping_of_pmf (pmf_of_multiset A) = Mapping.tabulate xs (\<lambda>x. count A x / real (size A))" 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   139
  using assms by (intro mapping_of_pmfI) (auto simp: lookup_tabulate)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   140
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   141
definition pmf_of_multiset_impl where
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   142
  "pmf_of_multiset_impl A = mapping_of_pmf (pmf_of_multiset A)"  
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   143
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   144
lemma pmf_of_multiset_impl_code_alt:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   145
  assumes "A \<noteq> {#}"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   146
  shows   "pmf_of_multiset_impl A =
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   147
             (let p = 1 / real (size A)
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66453
diff changeset
   148
              in  fold_mset (\<lambda>x. Mapping.map_default x 0 ((+) p)) Mapping.empty A)"
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   149
proof -
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   150
  define p where "p = 1 / real (size A)"
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66453
diff changeset
   151
  interpret comp_fun_commute "\<lambda>x. Mapping.map_default x 0 ((+) p)"
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   152
    unfolding Mapping.map_default_def [abs_def]
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   153
    by (standard, intro mapping_eqI ext) 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   154
       (simp_all add: o_def lookup_map_entry' lookup_default' lookup_default_def)
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66453
diff changeset
   155
  let ?m = "fold_mset (\<lambda>x. Mapping.map_default x 0 ((+) p)) Mapping.empty A"
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   156
  have keys: "Mapping.keys ?m = set_mset A" by (induction A) simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   157
  have lookup: "Mapping.lookup_default 0 ?m x = real (count A x) * p" for x
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   158
    by (induction A)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   159
       (simp_all add: lookup_map_default' lookup_default_def lookup_empty ring_distribs)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   160
  from keys lookup assms show ?thesis unfolding pmf_of_multiset_impl_def
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   161
    by (intro mapping_of_pmfI') (simp_all add: Let_def p_def)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   162
qed
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   163
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   164
lemma pmf_of_multiset_impl_code [code]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   165
  "pmf_of_multiset_impl (mset xs) =
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   166
     (if xs = [] then 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   167
        Code.abort (STR ''pmf_of_multiset of empty multiset'') 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   168
          (\<lambda>_. mapping_of_pmf (pmf_of_multiset (mset xs)))
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   169
      else let xs' = remdups xs; p = 1 / real (length xs) in
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   170
         Mapping.tabulate xs' (\<lambda>x. real (count (mset xs) x) * p))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   171
  using pmf_of_multiset_pmf_of_mapping[of "mset xs" "remdups xs"]
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   172
  by (simp add: pmf_of_multiset_impl_def)        
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   173
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   174
lemma pmf_of_multiset_code [code abstract]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   175
  "mapping_of_pmf (pmf_of_multiset A) = pmf_of_multiset_impl A"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   176
  by (simp add: pmf_of_multiset_impl_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   177
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   178
  
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   179
lemma bernoulli_pmf_code [code abstract]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   180
  "mapping_of_pmf (bernoulli_pmf p) = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   181
     (if p \<le> 0 then Mapping.update False 1 Mapping.empty 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   182
      else if p \<ge> 1 then Mapping.update True 1 Mapping.empty
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   183
      else Mapping.update False (1 - p) (Mapping.update True p Mapping.empty))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   184
  by (intro mapping_of_pmfI) (auto simp: bernoulli_pmf.rep_eq lookup_update' set_pmf_eq)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   185
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   186
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   187
lemma pmf_code [code]: "pmf p x = Mapping.lookup_default 0 (mapping_of_pmf p) x"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   188
  unfolding mapping_of_pmf_def Mapping.lookup_default_def
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   189
  by (auto split: option.splits simp: id_def Mapping.lookup.abs_eq)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   190
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   191
lemma set_pmf_code [code]: "set_pmf p = Mapping.keys (mapping_of_pmf p)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   192
  by transfer (auto simp: dom_def set_pmf_eq)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   193
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   194
lemma keys_mapping_of_pmf [simp]: "Mapping.keys (mapping_of_pmf p) = set_pmf p"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   195
  by transfer (auto simp: dom_def set_pmf_eq)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   196
  
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   197
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   198
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   199
definition fold_combine_plus where
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66453
diff changeset
   200
  "fold_combine_plus = comm_monoid_set.F (Mapping.combine ((+) :: real \<Rightarrow> _)) Mapping.empty"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   201
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   202
context
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   203
begin
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   204
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66453
diff changeset
   205
interpretation fold_combine_plus: combine_mapping_abel_semigroup "(+) :: real \<Rightarrow> _"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   206
  by unfold_locales (simp_all add: add_ac)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   207
  
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   208
qualified lemma lookup_default_fold_combine_plus: 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   209
  fixes A :: "'b set" and f :: "'b \<Rightarrow> ('a, real) mapping"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   210
  assumes "finite A"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   211
  shows   "Mapping.lookup_default 0 (fold_combine_plus f A) x = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   212
             (\<Sum>y\<in>A. Mapping.lookup_default 0 (f y) x)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   213
  unfolding fold_combine_plus_def using assms 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   214
    by (induction A rule: finite_induct) 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   215
       (simp_all add: lookup_default_empty lookup_default_neutral_combine)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   216
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   217
qualified lemma keys_fold_combine_plus: 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   218
  "finite A \<Longrightarrow> Mapping.keys (fold_combine_plus f A) = (\<Union>x\<in>A. Mapping.keys (f x))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   219
  by (simp add: fold_combine_plus_def fold_combine_plus.keys_fold_combine)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   220
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   221
qualified lemma fold_combine_plus_code [code]:
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66453
diff changeset
   222
  "fold_combine_plus g (set xs) = foldr (\<lambda>x. Mapping.combine (+) (g x)) (remdups xs) Mapping.empty"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   223
  by (simp add: fold_combine_plus_def fold_combine_plus.fold_combine_code)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   224
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   225
private lemma lookup_default_0_map_values:
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   226
  assumes "f x 0 = 0"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   227
  shows   "Mapping.lookup_default 0 (Mapping.map_values f m) x = f x (Mapping.lookup_default 0 m x)"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   228
  unfolding Mapping.lookup_default_def
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   229
  using assms by transfer (auto split: option.splits)
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   230
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   231
qualified lemma mapping_of_bind_pmf:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   232
  assumes "finite (set_pmf p)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   233
  shows   "mapping_of_pmf (bind_pmf p f) = 
69064
5840724b1d71 Prefix form of infix with * on either side no longer needs special treatment
nipkow
parents: 67399
diff changeset
   234
             fold_combine_plus (\<lambda>x. Mapping.map_values (\<lambda>_. (*) (pmf p x)) 
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   235
               (mapping_of_pmf (f x))) (set_pmf p)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   236
  using assms
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   237
  by (intro mapping_of_pmfI')
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   238
     (auto simp: keys_fold_combine_plus lookup_default_fold_combine_plus 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   239
                 pmf_bind integral_measure_pmf lookup_default_0_map_values 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   240
                 lookup_default_mapping_of_pmf mult_ac)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   241
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   242
lift_definition bind_pmf_aux :: "'a pmf \<Rightarrow> ('a \<Rightarrow> 'b pmf) \<Rightarrow> 'a set \<Rightarrow> ('b, real) mapping" is
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   243
  "\<lambda>(p :: 'a pmf) (f :: 'a \<Rightarrow> 'b pmf) (A::'a set) (x::'b). 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   244
     if x \<in> (\<Union>y\<in>A. set_pmf (f y)) then 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   245
       Some (measure_pmf.expectation p (\<lambda>y. indicator A y * pmf (f y) x)) 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   246
     else None" .
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   247
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   248
lemma keys_bind_pmf_aux [simp]:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   249
  "Mapping.keys (bind_pmf_aux p f A) = (\<Union>x\<in>A. set_pmf (f x))"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   250
  by transfer (auto split: if_splits)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   251
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   252
lemma lookup_default_bind_pmf_aux:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   253
  "Mapping.lookup_default 0 (bind_pmf_aux p f A) x = 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   254
     (if x \<in> (\<Union>y\<in>A. set_pmf (f y)) then 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   255
        measure_pmf.expectation p (\<lambda>y. indicator A y * pmf (f y) x) else 0)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   256
  unfolding lookup_default_def by transfer' simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   257
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   258
lemma lookup_default_bind_pmf_aux' [simp]:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   259
  "Mapping.lookup_default 0 (bind_pmf_aux p f (set_pmf p)) x = pmf (bind_pmf p f) x"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   260
  unfolding lookup_default_def
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   261
  by transfer (auto simp: pmf_bind AE_measure_pmf_iff set_pmf_eq
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   262
                    intro!: integral_cong_AE integral_eq_zero_AE)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   263
  
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   264
lemma bind_pmf_aux_correct:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   265
  "mapping_of_pmf (bind_pmf p f) = bind_pmf_aux p f (set_pmf p)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   266
  by (intro mapping_of_pmfI') simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   267
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   268
lemma bind_pmf_aux_code_aux:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   269
  assumes "finite A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   270
  shows   "bind_pmf_aux p f A = 
69064
5840724b1d71 Prefix form of infix with * on either side no longer needs special treatment
nipkow
parents: 67399
diff changeset
   271
             fold_combine_plus (\<lambda>x. Mapping.map_values (\<lambda>_. (*) (pmf p x))
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   272
               (mapping_of_pmf (f x))) A" (is "?lhs = ?rhs")
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   273
proof (intro mapping_eqI'[where d = 0])
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   274
  fix x assume "x \<in> Mapping.keys ?lhs"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   275
  then obtain y where y: "y \<in> A" "x \<in> set_pmf (f y)" by auto
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   276
  hence "Mapping.lookup_default 0 ?lhs x = 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   277
           measure_pmf.expectation p (\<lambda>y. indicator A y * pmf (f y) x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   278
    by (auto simp: lookup_default_bind_pmf_aux)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   279
  also from assms have "\<dots> = (\<Sum>y\<in>A. pmf p y * pmf (f y) x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   280
    by (subst integral_measure_pmf [of A])
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   281
       (auto simp: set_pmf_eq indicator_def mult_ac split: if_splits)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   282
  also from assms have "\<dots> = Mapping.lookup_default 0 ?rhs x"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   283
    by (simp add: lookup_default_fold_combine_plus lookup_default_0_map_values
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   284
          lookup_default_mapping_of_pmf)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   285
  finally show "Mapping.lookup_default 0 ?lhs x = Mapping.lookup_default 0 ?rhs x" .
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   286
qed (insert assms, simp_all add: keys_fold_combine_plus)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   287
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   288
lemma bind_pmf_aux_code [code]:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   289
  "bind_pmf_aux p f (set xs) = 
69064
5840724b1d71 Prefix form of infix with * on either side no longer needs special treatment
nipkow
parents: 67399
diff changeset
   290
     fold_combine_plus (\<lambda>x. Mapping.map_values (\<lambda>_. (*) (pmf p x))
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   291
               (mapping_of_pmf (f x))) (set xs)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   292
  by (rule bind_pmf_aux_code_aux) simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   293
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   294
lemmas bind_pmf_code [code abstract] = bind_pmf_aux_correct
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   295
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   296
end
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   297
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   298
hide_const (open) fold_combine_plus
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   299
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   300
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   301
lift_definition cond_pmf_impl :: "'a pmf \<Rightarrow> 'a set \<Rightarrow> ('a, real) mapping option" is
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   302
  "\<lambda>p A. if A \<inter> set_pmf p = {} then None else 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   303
     Some (\<lambda>x. if x \<in> A \<inter> set_pmf p then Some (pmf p x / measure_pmf.prob p A) else None)" .
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   304
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   305
lemma cond_pmf_impl_code_alt:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   306
  assumes "finite A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   307
  shows   "cond_pmf_impl p A = (
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   308
             let C = A \<inter> set_pmf p;
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   309
                 prob = (\<Sum>x\<in>C. pmf p x)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   310
             in  if prob = 0 then 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   311
                   None
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   312
                 else
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   313
                   Some (Mapping.map_values (\<lambda>_ y. y / prob) 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   314
                     (Mapping.filter (\<lambda>k _. k \<in> C) (mapping_of_pmf p))))"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   315
proof -
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   316
  define C where "C = A \<inter> set_pmf p"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   317
  define prob where "prob = (\<Sum>x\<in>C. pmf p x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   318
  also note C_def
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   319
  also from assms have "(\<Sum>x\<in>A \<inter> set_pmf p. pmf p x) = (\<Sum>x\<in>A. pmf p x)"
64267
b9a1486e79be setsum -> sum
nipkow
parents: 63882
diff changeset
   320
    by (intro sum.mono_neutral_left) (auto simp: set_pmf_eq)
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   321
  finally have prob1: "prob = (\<Sum>x\<in>A. pmf p x)" .
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   322
  hence prob2: "prob = measure_pmf.prob p A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   323
    using assms by (subst measure_measure_pmf_finite) simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   324
  have prob3: "prob = 0 \<longleftrightarrow> A \<inter> set_pmf p = {}"
64267
b9a1486e79be setsum -> sum
nipkow
parents: 63882
diff changeset
   325
    by (subst prob1, subst sum_nonneg_eq_0_iff) (auto simp: set_pmf_eq assms)
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   326
  from assms have prob4: "prob = measure_pmf.prob p C"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   327
    unfolding prob_def by (intro measure_measure_pmf_finite [symmetric]) (simp_all add: C_def)
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   328
  
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   329
  show ?thesis
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   330
  proof (cases "prob = 0")
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   331
    case True
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   332
    hence "A \<inter> set_pmf p = {}" by (subst (asm) prob3)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   333
    with True show ?thesis by (simp add: Let_def prob_def C_def cond_pmf_impl.abs_eq)
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   334
  next
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   335
    case False
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   336
    hence A: "C \<noteq> {}" unfolding C_def by (subst (asm) prob3) auto
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   337
    with prob3 have prob_nz: "prob \<noteq> 0" by (auto simp: C_def)
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   338
    fix x
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   339
    have "cond_pmf_impl p A = 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   340
            Some (mapping.Mapping (\<lambda>x. if x \<in> C then 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   341
              Some (pmf p x / measure_pmf.prob p C) else None))" 
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   342
         (is "_ = Some ?m")
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   343
      using A prob2 prob4 unfolding C_def by transfer (auto simp: fun_eq_iff)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   344
    also have "?m = Mapping.map_values (\<lambda>_ y. y / prob) 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   345
                 (Mapping.filter (\<lambda>k _. k \<in> C) (mapping_of_pmf p))"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   346
      using prob_nz prob4 assms unfolding C_def
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   347
      by transfer (auto simp: fun_eq_iff set_pmf_eq)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   348
    finally show ?thesis using False by (simp add: Let_def prob_def C_def)
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   349
  qed
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   350
qed
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   351
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   352
lemma cond_pmf_impl_code [code]:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   353
  "cond_pmf_impl p (set xs) = (
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   354
     let C = set xs \<inter> set_pmf p;
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   355
         prob = (\<Sum>x\<in>C. pmf p x)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   356
     in  if prob = 0 then 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   357
           None
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   358
         else
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   359
           Some (Mapping.map_values (\<lambda>_ y. y / prob) 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   360
             (Mapping.filter (\<lambda>k _. k \<in> C) (mapping_of_pmf p))))"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   361
  by (rule cond_pmf_impl_code_alt) simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   362
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   363
lemma cond_pmf_code [code abstract]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   364
  "mapping_of_pmf (cond_pmf p A) = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   365
     (case cond_pmf_impl p A of
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   366
        None \<Rightarrow> Code.abort (STR ''cond_pmf with set of probability 0'')
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   367
                  (\<lambda>_. mapping_of_pmf (cond_pmf p A))
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   368
      | Some m \<Rightarrow> m)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   369
proof (cases "cond_pmf_impl p A")
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   370
  case (Some m)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   371
  hence A: "set_pmf p \<inter> A \<noteq> {}" by transfer (auto split: if_splits)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   372
  from Some have B: "Mapping.keys m = set_pmf (cond_pmf p A)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   373
    by (subst set_cond_pmf[OF A], transfer) (auto split: if_splits)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   374
  with Some A have "mapping_of_pmf (cond_pmf p A) = m"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   375
    by (intro mapping_of_pmfI[OF _ B], transfer) (auto split: if_splits simp: pmf_cond)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   376
  with Some show ?thesis by simp
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   377
qed simp_all
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   378
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   379
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   380
lemma binomial_pmf_code [code abstract]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   381
  "mapping_of_pmf (binomial_pmf n p) = (
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   382
     if p < 0 \<or> p > 1 then 
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   383
       Code.abort (STR ''binomial_pmf with invalid probability'') 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   384
         (\<lambda>_. mapping_of_pmf (binomial_pmf n p))
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   385
     else if p = 0 then Mapping.update 0 1 Mapping.empty
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   386
     else if p = 1 then Mapping.update n 1 Mapping.empty
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   387
     else Mapping.tabulate [0..<Suc n] (\<lambda>k. real (n choose k) * p ^ k * (1 - p) ^ (n - k)))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   388
  by (cases "p < 0 \<or> p > 1")
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   389
     (simp, intro mapping_of_pmfI, 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   390
      auto simp: lookup_update' lookup_empty set_pmf_binomial_eq lookup_tabulate split: if_splits)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   391
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   392
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   393
lemma pred_pmf_code [code]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   394
  "pred_pmf P p = (\<forall>x\<in>set_pmf p. P x)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   395
  by (auto simp: pred_pmf_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   396
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   397
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   398
lemma mapping_of_pmf_pmf_of_list:
63882
018998c00003 renamed listsum -> sum_list, listprod ~> prod_list
nipkow
parents: 63793
diff changeset
   399
  assumes "\<And>x. x \<in> snd ` set xs \<Longrightarrow> x > 0" "sum_list (map snd xs) = 1"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   400
  shows   "mapping_of_pmf (pmf_of_list xs) = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   401
             Mapping.tabulate (remdups (map fst xs)) 
63882
018998c00003 renamed listsum -> sum_list, listprod ~> prod_list
nipkow
parents: 63793
diff changeset
   402
               (\<lambda>x. sum_list (map snd (filter (\<lambda>z. fst z = x) xs)))"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   403
proof -
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   404
  from assms have wf: "pmf_of_list_wf xs" by (intro pmf_of_list_wfI) force
63539
70d4d9e5707b tuned proofs -- avoid improper use of "this";
wenzelm
parents: 63195
diff changeset
   405
  with assms have "set_pmf (pmf_of_list xs) = fst ` set xs"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   406
    by (intro set_pmf_of_list_eq) auto
63539
70d4d9e5707b tuned proofs -- avoid improper use of "this";
wenzelm
parents: 63195
diff changeset
   407
  with wf show ?thesis
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   408
    by (intro mapping_of_pmfI) (auto simp: lookup_tabulate pmf_pmf_of_list)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   409
qed
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   410
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   411
lemma mapping_of_pmf_pmf_of_list':
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   412
  assumes "pmf_of_list_wf xs"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   413
  defines "xs' \<equiv> filter (\<lambda>z. snd z \<noteq> 0) xs"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   414
  shows   "mapping_of_pmf (pmf_of_list xs) = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   415
             Mapping.tabulate (remdups (map fst xs')) 
63882
018998c00003 renamed listsum -> sum_list, listprod ~> prod_list
nipkow
parents: 63793
diff changeset
   416
               (\<lambda>x. sum_list (map snd (filter (\<lambda>z. fst z = x) xs')))" (is "_ = ?rhs") 
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   417
proof -
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   418
  have wf: "pmf_of_list_wf xs'" unfolding xs'_def by (rule pmf_of_list_remove_zeros) fact
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   419
  have pos: "\<forall>x\<in>snd`set xs'. x > 0" using assms(1) unfolding xs'_def
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   420
    by (force simp: pmf_of_list_wf_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   421
  from assms have "pmf_of_list xs = pmf_of_list xs'" 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   422
    unfolding xs'_def by (subst pmf_of_list_remove_zeros) simp_all
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   423
  also from wf pos have "mapping_of_pmf \<dots> = ?rhs"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   424
    by (intro mapping_of_pmf_pmf_of_list) (auto simp: pmf_of_list_wf_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   425
  finally show ?thesis .
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   426
qed
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   427
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   428
lemma pmf_of_list_wf_code [code]:
63882
018998c00003 renamed listsum -> sum_list, listprod ~> prod_list
nipkow
parents: 63793
diff changeset
   429
  "pmf_of_list_wf xs \<longleftrightarrow> list_all (\<lambda>z. snd z \<ge> 0) xs \<and> sum_list (map snd xs) = 1"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   430
  by (auto simp add: pmf_of_list_wf_def list_all_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   431
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   432
lemma pmf_of_list_code [code abstract]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   433
  "mapping_of_pmf (pmf_of_list xs) = (
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   434
     if pmf_of_list_wf xs then
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   435
       let xs' = filter (\<lambda>z. snd z \<noteq> 0) xs
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   436
       in  Mapping.tabulate (remdups (map fst xs')) 
63882
018998c00003 renamed listsum -> sum_list, listprod ~> prod_list
nipkow
parents: 63793
diff changeset
   437
             (\<lambda>x. sum_list (map snd (filter (\<lambda>z. fst z = x) xs')))
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   438
     else
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   439
       Code.abort (STR ''Invalid list for pmf_of_list'') (\<lambda>_. mapping_of_pmf (pmf_of_list xs)))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   440
  using mapping_of_pmf_pmf_of_list'[of xs] by (simp add: Let_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   441
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   442
lemma mapping_of_pmf_eq_iff [simp]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   443
  "mapping_of_pmf p = mapping_of_pmf q \<longleftrightarrow> p = (q :: 'a pmf)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   444
proof (transfer, intro iffI pmf_eqI)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   445
  fix p q :: "'a pmf" and x :: 'a
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   446
  assume "(\<lambda>x. if pmf p x = 0 then None else Some (pmf p x)) =
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   447
            (\<lambda>x. if pmf q x = 0 then None else Some (pmf q x))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   448
  hence "(if pmf p x = 0 then None else Some (pmf p x)) =
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   449
           (if pmf q x = 0 then None else Some (pmf q x))" for x
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   450
    by (simp add: fun_eq_iff)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   451
  from this[of x] show "pmf p x = pmf q x" by (auto split: if_splits)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   452
qed (simp_all cong: if_cong)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   453
63195
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   454
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   455
subsection \<open>Code abbreviations for integrals and probabilities\<close>
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   456
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   457
text \<open>
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   458
  Integrals and probabilities are defined for general measures, so we cannot give any
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   459
  code equations directly. We can, however, specialise these constants them to PMFs, 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   460
  give code equations for these specialised constants, and tell the code generator 
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   461
  to unfold the original constants to the specialised ones whenever possible.
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   462
\<close>
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   463
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   464
definition pmf_integral where
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   465
  "pmf_integral p f = lebesgue_integral (measure_pmf p) (f :: _ \<Rightarrow> real)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   466
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   467
definition pmf_set_integral where
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   468
  "pmf_set_integral p f A = lebesgue_integral (measure_pmf p) (\<lambda>x. indicator A x * f x :: real)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   469
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   470
definition pmf_prob where
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   471
  "pmf_prob p A = measure_pmf.prob p A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   472
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   473
lemma pmf_prob_compl: "pmf_prob p (-A) = 1 - pmf_prob p A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   474
  using measure_pmf.prob_compl[of A p] by (simp add: pmf_prob_def Compl_eq_Diff_UNIV)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   475
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   476
lemma pmf_integral_pmf_set_integral [code]:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   477
  "pmf_integral p f = pmf_set_integral p f (set_pmf p)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   478
  unfolding pmf_integral_def pmf_set_integral_def
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   479
  by (intro integral_cong_AE) (simp_all add: AE_measure_pmf_iff)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   480
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   481
lemma pmf_prob_pmf_set_integral:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   482
  "pmf_prob p A = pmf_set_integral p (\<lambda>_. 1) A"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   483
  by (simp add: pmf_prob_def pmf_set_integral_def)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   484
  
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   485
lemma pmf_set_integral_code_alt_finite:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   486
  "finite A \<Longrightarrow> pmf_set_integral p f A = (\<Sum>x\<in>A. pmf p x * f x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   487
  unfolding pmf_set_integral_def
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   488
  by (subst integral_measure_pmf[of A]) (auto simp: indicator_def mult_ac split: if_splits)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   489
  
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   490
lemma pmf_set_integral_code [code]:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   491
  "pmf_set_integral p f (set xs) = (\<Sum>x\<in>set xs. pmf p x * f x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   492
  by (rule pmf_set_integral_code_alt_finite) simp_all
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   493
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   494
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   495
lemma pmf_prob_code_alt_finite:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   496
  "finite A \<Longrightarrow> pmf_prob p A = (\<Sum>x\<in>A. pmf p x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   497
  by (simp add: pmf_prob_pmf_set_integral pmf_set_integral_code_alt_finite)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   498
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   499
lemma pmf_prob_code [code]:
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   500
  "pmf_prob p (set xs) = (\<Sum>x\<in>set xs. pmf p x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   501
  "pmf_prob p (List.coset xs) = 1 - (\<Sum>x\<in>set xs. pmf p x)"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   502
  by (simp_all add: pmf_prob_code_alt_finite pmf_prob_compl)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   503
  
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   504
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   505
lemma pmf_prob_code_unfold [code_abbrev]: "pmf_prob p = measure_pmf.prob p"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   506
  by (intro ext) (simp add: pmf_prob_def)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   507
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   508
(* FIXME: Why does this not work without parameters? *)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   509
lemma pmf_integral_code_unfold [code_abbrev]: "pmf_integral p = measure_pmf.expectation p"
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   510
  by (intro ext) (simp add: pmf_integral_def)
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   511
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   512
f3f08c0d4aaf Tuned code equations for mappings and PMFs
eberlm
parents: 63194
diff changeset
   513
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   514
definition "pmf_of_alist xs = embed_pmf (\<lambda>x. case map_of xs x of Some p \<Rightarrow> p | None \<Rightarrow> 0)"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   515
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   516
lemma pmf_of_mapping_Mapping [code_post]:
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   517
    "pmf_of_mapping (Mapping xs) = pmf_of_alist xs"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   518
  unfolding pmf_of_mapping_def Mapping.lookup_default_def [abs_def] pmf_of_alist_def
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   519
  by transfer simp_all
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   520
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   521
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   522
instantiation pmf :: (equal) equal
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   523
begin
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   524
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   525
definition "equal_pmf p q = (mapping_of_pmf p = mapping_of_pmf (q :: 'a pmf))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   526
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   527
instance by standard (simp add: equal_pmf_def)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   528
end
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   529
63793
e68a0b651eb5 add_mset constructor in multisets
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents: 63539
diff changeset
   530
definition single :: "'a \<Rightarrow> 'a multiset" where
e68a0b651eb5 add_mset constructor in multisets
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents: 63539
diff changeset
   531
"single s = {#s#}"
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   532
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   533
definition (in term_syntax)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   534
  pmfify :: "('a::typerep multiset \<times> (unit \<Rightarrow> Code_Evaluation.term)) \<Rightarrow>
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   535
             'a \<times> (unit \<Rightarrow> Code_Evaluation.term) \<Rightarrow>
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   536
             'a pmf \<times> (unit \<Rightarrow> Code_Evaluation.term)" where
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   537
  [code_unfold]: "pmfify A x =  
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   538
    Code_Evaluation.valtermify pmf_of_multiset {\<cdot>} 
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66453
diff changeset
   539
      (Code_Evaluation.valtermify (+) {\<cdot>} A {\<cdot>} 
63194
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   540
       (Code_Evaluation.valtermify single {\<cdot>} x))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   541
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   542
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   543
notation fcomp (infixl "\<circ>>" 60)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   544
notation scomp (infixl "\<circ>\<rightarrow>" 60)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   545
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   546
instantiation pmf :: (random) random
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   547
begin
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   548
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   549
definition
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   550
  "Quickcheck_Random.random i = 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   551
     Quickcheck_Random.random i \<circ>\<rightarrow> (\<lambda>A. 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   552
       Quickcheck_Random.random i \<circ>\<rightarrow> (\<lambda>x. Pair (pmfify A x)))"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   553
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   554
instance ..
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   555
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   556
end
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   557
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   558
no_notation fcomp (infixl "\<circ>>" 60)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   559
no_notation scomp (infixl "\<circ>\<rightarrow>" 60)
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   560
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   561
instantiation pmf :: (full_exhaustive) full_exhaustive
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   562
begin
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   563
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   564
definition full_exhaustive_pmf :: "('a pmf \<times> (unit \<Rightarrow> term) \<Rightarrow> (bool \<times> term list) option) \<Rightarrow> natural \<Rightarrow> (bool \<times> term list) option"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   565
where
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   566
  "full_exhaustive_pmf f i =
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   567
     Quickcheck_Exhaustive.full_exhaustive (\<lambda>A. 
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   568
       Quickcheck_Exhaustive.full_exhaustive (\<lambda>x. f (pmfify A x)) i) i"
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   569
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   570
instance ..
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   571
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   572
end
0b7bdb75f451 Added code generation for PMFs
eberlm
parents:
diff changeset
   573
64267
b9a1486e79be setsum -> sum
nipkow
parents: 63882
diff changeset
   574
end