author | haftmann |
Mon, 06 Jul 2009 14:19:13 +0200 | |
changeset 31949 | 3f933687fae9 |
parent 31636 | 138625ae4067 |
child 32740 | 9dd0a2f83429 |
permissions | -rw-r--r-- |
29815
9e94b7078fa5
mandatory prefix for index conversion operations
haftmann
parents:
29806
diff
changeset
|
1 |
(* Author: Florian Haftmann, TU Muenchen *) |
22528 | 2 |
|
26265 | 3 |
header {* A HOL random engine *} |
22528 | 4 |
|
5 |
theory Random |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
6 |
imports Code_Numeral List |
22528 | 7 |
begin |
8 |
||
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
9 |
notation fcomp (infixl "o>" 60) |
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
10 |
notation scomp (infixl "o\<rightarrow>" 60) |
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
11 |
|
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
12 |
|
26265 | 13 |
subsection {* Auxiliary functions *} |
14 |
||
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
15 |
definition inc_shift :: "code_numeral \<Rightarrow> code_numeral \<Rightarrow> code_numeral" where |
26265 | 16 |
"inc_shift v k = (if v = k then 1 else k + 1)" |
17 |
||
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
18 |
definition minus_shift :: "code_numeral \<Rightarrow> code_numeral \<Rightarrow> code_numeral \<Rightarrow> code_numeral" where |
26265 | 19 |
"minus_shift r k l = (if k < l then r + k - l else k - l)" |
20 |
||
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
21 |
fun log :: "code_numeral \<Rightarrow> code_numeral \<Rightarrow> code_numeral" where |
26265 | 22 |
"log b i = (if b \<le> 1 \<or> i < b then 1 else 1 + log b (i div b))" |
23 |
||
30495 | 24 |
|
26265 | 25 |
subsection {* Random seeds *} |
26038 | 26 |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
27 |
types seed = "code_numeral \<times> code_numeral" |
22528 | 28 |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
29 |
primrec "next" :: "seed \<Rightarrow> code_numeral \<times> seed" where |
26265 | 30 |
"next (v, w) = (let |
31 |
k = v div 53668; |
|
32 |
v' = minus_shift 2147483563 (40014 * (v mod 53668)) (k * 12211); |
|
33 |
l = w div 52774; |
|
34 |
w' = minus_shift 2147483399 (40692 * (w mod 52774)) (l * 3791); |
|
35 |
z = minus_shift 2147483562 v' (w' + 1) + 1 |
|
36 |
in (z, (v', w')))" |
|
37 |
||
38 |
lemma next_not_0: |
|
39 |
"fst (next s) \<noteq> 0" |
|
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
40 |
by (cases s) (auto simp add: minus_shift_def Let_def) |
26265 | 41 |
|
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
42 |
primrec seed_invariant :: "seed \<Rightarrow> bool" where |
26265 | 43 |
"seed_invariant (v, w) \<longleftrightarrow> 0 < v \<and> v < 9438322952 \<and> 0 < w \<and> True" |
44 |
||
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
45 |
definition split_seed :: "seed \<Rightarrow> seed \<times> seed" where |
26038 | 46 |
"split_seed s = (let |
47 |
(v, w) = s; |
|
48 |
(v', w') = snd (next s); |
|
26265 | 49 |
v'' = inc_shift 2147483562 v; |
26038 | 50 |
s'' = (v'', w'); |
26265 | 51 |
w'' = inc_shift 2147483398 w; |
26038 | 52 |
s''' = (v', w'') |
53 |
in (s'', s'''))" |
|
54 |
||
55 |
||
26265 | 56 |
subsection {* Base selectors *} |
22528 | 57 |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
58 |
fun iterate :: "code_numeral \<Rightarrow> ('b \<Rightarrow> 'a \<Rightarrow> 'b \<times> 'a) \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow> 'b \<times> 'a" where |
30495 | 59 |
"iterate k f x = (if k = 0 then Pair x else f x o\<rightarrow> iterate (k - 1) f)" |
22528 | 60 |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
61 |
definition range :: "code_numeral \<Rightarrow> seed \<Rightarrow> code_numeral \<times> seed" where |
30495 | 62 |
"range k = iterate (log 2147483561 k) |
63 |
(\<lambda>l. next o\<rightarrow> (\<lambda>v. Pair (v + l * 2147483561))) 1 |
|
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
64 |
o\<rightarrow> (\<lambda>v. Pair (v mod k))" |
26265 | 65 |
|
66 |
lemma range: |
|
30495 | 67 |
"k > 0 \<Longrightarrow> fst (range k s) < k" |
68 |
by (simp add: range_def scomp_apply split_def del: log.simps iterate.simps) |
|
26038 | 69 |
|
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
70 |
definition select :: "'a list \<Rightarrow> seed \<Rightarrow> 'a \<times> seed" where |
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
71 |
"select xs = range (Code_Numeral.of_nat (length xs)) |
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
72 |
o\<rightarrow> (\<lambda>k. Pair (nth xs (Code_Numeral.nat_of k)))" |
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
73 |
|
26265 | 74 |
lemma select: |
75 |
assumes "xs \<noteq> []" |
|
76 |
shows "fst (select xs s) \<in> set xs" |
|
77 |
proof - |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
78 |
from assms have "Code_Numeral.of_nat (length xs) > 0" by simp |
26265 | 79 |
with range have |
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
80 |
"fst (range (Code_Numeral.of_nat (length xs)) s) < Code_Numeral.of_nat (length xs)" by best |
26265 | 81 |
then have |
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
82 |
"Code_Numeral.nat_of (fst (range (Code_Numeral.of_nat (length xs)) s)) < length xs" by simp |
26265 | 83 |
then show ?thesis |
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
84 |
by (simp add: scomp_apply split_beta select_def) |
26265 | 85 |
qed |
22528 | 86 |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
87 |
primrec pick :: "(code_numeral \<times> 'a) list \<Rightarrow> code_numeral \<Rightarrow> 'a" where |
31180 | 88 |
"pick (x # xs) i = (if i < fst x then snd x else pick xs (i - fst x))" |
89 |
||
90 |
lemma pick_member: |
|
91 |
"i < listsum (map fst xs) \<Longrightarrow> pick xs i \<in> set (map snd xs)" |
|
92 |
by (induct xs arbitrary: i) simp_all |
|
93 |
||
94 |
lemma pick_drop_zero: |
|
95 |
"pick (filter (\<lambda>(k, _). k > 0) xs) = pick xs" |
|
96 |
by (induct xs) (auto simp add: expand_fun_eq) |
|
97 |
||
31203
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
98 |
lemma pick_same: |
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
99 |
"l < length xs \<Longrightarrow> Random.pick (map (Pair 1) xs) (Code_Numeral.of_nat l) = nth xs l" |
31203
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
100 |
proof (induct xs arbitrary: l) |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
101 |
case Nil then show ?case by simp |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
102 |
next |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
103 |
case (Cons x xs) then show ?case by (cases l) simp_all |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
104 |
qed |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
105 |
|
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
106 |
definition select_weight :: "(code_numeral \<times> 'a) list \<Rightarrow> seed \<Rightarrow> 'a \<times> seed" where |
31180 | 107 |
"select_weight xs = range (listsum (map fst xs)) |
108 |
o\<rightarrow> (\<lambda>k. Pair (pick xs k))" |
|
109 |
||
110 |
lemma select_weight_member: |
|
111 |
assumes "0 < listsum (map fst xs)" |
|
112 |
shows "fst (select_weight xs s) \<in> set (map snd xs)" |
|
113 |
proof - |
|
114 |
from range assms |
|
115 |
have "fst (range (listsum (map fst xs)) s) < listsum (map fst xs)" . |
|
116 |
with pick_member |
|
117 |
have "pick xs (fst (range (listsum (map fst xs)) s)) \<in> set (map snd xs)" . |
|
118 |
then show ?thesis by (simp add: select_weight_def scomp_def split_def) |
|
119 |
qed |
|
120 |
||
31268 | 121 |
lemma select_weight_cons_zero: |
122 |
"select_weight ((0, x) # xs) = select_weight xs" |
|
123 |
by (simp add: select_weight_def) |
|
124 |
||
31203
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
125 |
lemma select_weigth_drop_zero: |
31261 | 126 |
"select_weight (filter (\<lambda>(k, _). k > 0) xs) = select_weight xs" |
31203
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
127 |
proof - |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
128 |
have "listsum (map fst [(k, _)\<leftarrow>xs . 0 < k]) = listsum (map fst xs)" |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
129 |
by (induct xs) auto |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
130 |
then show ?thesis by (simp only: select_weight_def pick_drop_zero) |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
131 |
qed |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
132 |
|
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
133 |
lemma select_weigth_select: |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
134 |
assumes "xs \<noteq> []" |
31261 | 135 |
shows "select_weight (map (Pair 1) xs) = select xs" |
31203
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
136 |
proof - |
31261 | 137 |
have less: "\<And>s. fst (range (Code_Numeral.of_nat (length xs)) s) < Code_Numeral.of_nat (length xs)" |
31203
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
138 |
using assms by (intro range) simp |
31205
98370b26c2ce
String.literal replaces message_string, code_numeral replaces (code_)index
haftmann
parents:
31203
diff
changeset
|
139 |
moreover have "listsum (map fst (map (Pair 1) xs)) = Code_Numeral.of_nat (length xs)" |
31203
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
140 |
by (induct xs) simp_all |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
141 |
ultimately show ?thesis |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
142 |
by (auto simp add: select_weight_def select_def scomp_def split_def |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
143 |
expand_fun_eq pick_same [symmetric]) |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
144 |
qed |
5c8fb4fd67e0
moved Code_Index, Random and Quickcheck before Main
haftmann
parents:
31196
diff
changeset
|
145 |
|
26265 | 146 |
|
147 |
subsection {* @{text ML} interface *} |
|
22528 | 148 |
|
149 |
ML {* |
|
26265 | 150 |
structure Random_Engine = |
22528 | 151 |
struct |
152 |
||
26038 | 153 |
type seed = int * int; |
22528 | 154 |
|
155 |
local |
|
26038 | 156 |
|
26265 | 157 |
val seed = ref |
158 |
(let |
|
159 |
val now = Time.toMilliseconds (Time.now ()); |
|
26038 | 160 |
val (q, s1) = IntInf.divMod (now, 2147483562); |
161 |
val s2 = q mod 2147483398; |
|
26265 | 162 |
in (s1 + 1, s2 + 1) end); |
163 |
||
22528 | 164 |
in |
26038 | 165 |
|
166 |
fun run f = |
|
167 |
let |
|
26265 | 168 |
val (x, seed') = f (! seed); |
26038 | 169 |
val _ = seed := seed' |
170 |
in x end; |
|
171 |
||
22528 | 172 |
end; |
173 |
||
174 |
end; |
|
175 |
*} |
|
176 |
||
31180 | 177 |
hide (open) type seed |
178 |
hide (open) const inc_shift minus_shift log "next" seed_invariant split_seed |
|
31636 | 179 |
iterate range select pick select_weight |
31180 | 180 |
|
29823
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
181 |
no_notation fcomp (infixl "o>" 60) |
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
182 |
no_notation scomp (infixl "o\<rightarrow>" 60) |
0ab754d13ccd
session Reflecion renamed to Decision_Procs, moved Dense_Linear_Order there
haftmann
parents:
29815
diff
changeset
|
183 |
|
26038 | 184 |
end |
28145 | 185 |