-
Notifications
You must be signed in to change notification settings - Fork 0
/
Move_R.thy
253 lines (224 loc) · 10.4 KB
/
Move_R.thy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*)
(* Arch generic lemmas that should be moved into theory files before Refine *)
theory Move_R
imports
"AInvs.ArchDetSchedSchedule_AI"
begin
lemma zip_map_rel:
assumes "(x,y) \<in> set (zip xs ys)" "map f xs = map g ys"
shows "f x = g y"
using assms by (induct xs arbitrary: x y ys; cases ys) auto
lemma fold_K:
"(P and (\<lambda> s. Q)) = (P and K Q)"
by simp
(* Move to lib *)
lemmas FalseI = notE[where R=False]
(* Move to Lib *)
lemma nonempty_cross_distinct_singleton_elim:
"\<lbrakk> x \<times> {a} = y \<times> {b};
x \<noteq> {} \<or> y \<noteq> {};
a \<noteq> b \<rbrakk>
\<Longrightarrow> P"
by blast
lemma no_other_bits_set:
"\<lbrakk> (w::'a::len word) && ~~ (2 ^ n) = 0 ; n' \<noteq> n ; n < size w ; n' < size w \<rbrakk>
\<Longrightarrow> \<not> w !! n'"
by (fastforce dest!: word_eqD simp: word_ops_nth_size word_size nth_w2p)
lemma mask_out_0:
"\<lbrakk>x \<le> 2^n-1; n < LENGTH('a)\<rbrakk> \<Longrightarrow> (x::'a::len word) && ~~ mask n = 0"
by (clarsimp simp: mask_out_sub_mask less_mask_eq)
lemma mask_out_first_mask_some_eq:
"\<lbrakk> x && ~~ mask n = y && ~~ mask n; n \<le> m \<rbrakk> \<Longrightarrow> x && ~~ mask m = y && ~~ mask m"
apply (rule word_eqI, rename_tac n')
apply (drule_tac x=n' in word_eqD)
apply (auto simp: word_ops_nth_size word_size)
done
lemma unaligned_helper:
"\<lbrakk>is_aligned x n; y\<noteq>0; y < 2 ^ n\<rbrakk> \<Longrightarrow> \<not> is_aligned (x + y) n"
apply (simp (no_asm_simp) add: is_aligned_mask)
apply (simp add: mask_add_aligned)
apply (cut_tac mask_eq_iff_w2p[of n y], simp_all add: word_size)
apply (rule ccontr)
apply (simp add: not_less power_overflow word_bits_conv)
done
declare word_unat_power[symmetric, simp del]
lemma oblivious_mapM_x:
"\<forall>x\<in>set xs. oblivious f (g x) \<Longrightarrow> oblivious f (mapM_x g xs)"
by (induct xs) (auto simp: mapM_x_Nil mapM_x_Cons oblivious_bind)
(* Should probably become part of the hoare_vgc_if_lift2 set *)
lemma hoare_vcg_if_lift3:
"\<lbrace>R\<rbrace> f \<lbrace>\<lambda>rv s. (P rv s \<longrightarrow> X rv s) \<and> (\<not> P rv s \<longrightarrow> Y rv s)\<rbrace> \<Longrightarrow>
\<lbrace>R\<rbrace> f \<lbrace>\<lambda>rv s. (if P rv s then X rv else Y rv) s\<rbrace>"
by auto
lemmas hoare_pre_post = hoare_pre_imp[where R="\<lambda>_. Q" and Q=Q for Q]
lemmas corres_underlying_gets_pre_rhs =
corres_symb_exec_r[OF _ _ gets_inv no_fail_pre[OF non_fail_gets TrueI]]
lemma corres_if_r':
"\<lbrakk> G' \<Longrightarrow> corres_underlying sr nf nf' r P P' a c; \<not>G' \<Longrightarrow> corres_underlying sr nf nf' r P Q' a d \<rbrakk>
\<Longrightarrow> corres_underlying sr nf nf' r (P) (if G' then P' else Q')
(a) (if G' then c else d)"
by simp
lemma valid_corres_combined:
assumes "valid P f Q"
assumes "corres_underlying sr False nf' rr P P' f f'"
assumes "valid (\<lambda>s'. \<exists>s. (s,s')\<in>sr \<and> P s \<and> P' s') f' Q'" (is "valid ?P _ _")
shows "valid ?P f' (\<lambda>r' s'. \<exists>r s. (s,s') \<in> sr \<and> Q r s \<and> Q' r' s' \<and> rr r r')"
using assms
by (fastforce simp: valid_def corres_underlying_def split_def)
(* Move the following 3 to Lib *)
lemma corres_noop3:
assumes x: "\<And>s s'. \<lbrakk>P s; P' s'; (s, s') \<in> sr\<rbrakk> \<Longrightarrow> \<lbrace>(=) s\<rbrace> f \<exists>\<lbrace>\<lambda>r. (=) s\<rbrace>"
assumes y: "\<And>s s'. \<lbrakk>P s; P' s'; (s, s') \<in> sr\<rbrakk> \<Longrightarrow> \<lbrace>(=) s'\<rbrace> g \<lbrace>\<lambda>r. (=) s'\<rbrace>"
assumes z: "nf' \<Longrightarrow> no_fail P' g"
shows "corres_underlying sr nf nf' dc P P' f g"
apply (clarsimp simp: corres_underlying_def)
apply (rule conjI)
apply clarsimp
apply (rule use_exs_valid)
apply (rule exs_hoare_post_imp)
prefer 2
apply (rule x)
apply assumption+
apply simp_all
apply (subgoal_tac "ba = b")
apply simp
apply (rule sym)
apply (rule use_valid[OF _ y], assumption+)
apply simp
apply (insert z)
apply (clarsimp simp: no_fail_def)
done
lemma corres_symb_exec_l':
assumes z: "\<And>rv. corres_underlying sr nf nf' r (Q' rv) P' (x rv) y"
assumes x: "\<And>s. P s \<Longrightarrow> \<lbrace>(=) s\<rbrace> m \<exists>\<lbrace>\<lambda>r. (=) s\<rbrace>"
assumes y: "\<lbrace>Q\<rbrace> m \<lbrace>Q'\<rbrace>"
shows "corres_underlying sr nf nf' r (P and Q) P' (m >>= (\<lambda>rv. x rv)) y"
apply (rule corres_guard_imp)
apply (subst gets_bind_ign[symmetric], rule corres_split)
apply (rule z)
apply (rule corres_noop3)
apply (erule x)
apply (rule gets_wp)
apply (rule non_fail_gets)
apply (rule y)
apply (rule gets_wp)
apply simp+
done
lemma corres_symb_exec_r':
assumes z: "\<And>rv. corres_underlying sr nf nf' r P (P'' rv) x (y rv)"
assumes y: "\<lbrace>P'\<rbrace> m \<lbrace>P''\<rbrace>"
assumes x: "\<And>s. Q' s \<Longrightarrow> \<lbrace>(=) s\<rbrace> m \<lbrace>\<lambda>r. (=) s\<rbrace>"
assumes nf: "nf' \<Longrightarrow> no_fail R' m"
shows "corres_underlying sr nf nf' r P (P' and Q' and R') x (m >>= (\<lambda>rv. y rv))"
apply (rule corres_guard_imp)
apply (subst gets_bind_ign[symmetric], rule corres_split)
apply (rule z)
apply (rule_tac P'="a' and a''" for a' a'' in corres_noop3)
apply (simp add: simpler_gets_def exs_valid_def)
apply clarsimp
apply (erule x)
apply (rule no_fail_pre)
apply (erule nf)
apply clarsimp
apply assumption
apply (rule gets_wp)
apply (rule y)
apply simp+
done
lemma get_mapM_x_lower:
fixes P :: "'a option \<Rightarrow> 's \<Rightarrow> bool"
fixes f :: "('s,'a) nondet_monad"
fixes g :: "'a \<Rightarrow> 'b \<Rightarrow> ('s,'c) nondet_monad"
\<comment> \<open>@{term g} preserves the state that @{term f} cares about\<close>
assumes g: "\<And>x y. \<lbrace> P (Some x) \<rbrace> g x y \<lbrace> \<lambda>_. P (Some x) \<rbrace>"
\<comment> \<open>@{term P} specifies whether @{term f} either fails or returns a deterministic result\<close>
assumes f: "\<And>opt_x s. P opt_x s \<Longrightarrow> f s = case_option ({},True) (\<lambda>x. ({(x,s)},False)) opt_x"
\<comment> \<open>Every state determines P, and therefore the behaviour of @{term f}\<close>
assumes x: "\<And>s. \<exists> opt_x. P opt_x s"
\<comment> \<open>If @{term f} may fail, ensure there is at least one @{term f}\<close>
assumes y: "\<exists>s. P None s \<Longrightarrow> ys \<noteq> []"
shows "do x \<leftarrow> f; mapM_x (g x) ys od = mapM_x (\<lambda>y. do x \<leftarrow> f; g x y od) ys"
proof -
have f_rv: "\<lbrace>\<top>\<rbrace> f \<lbrace>\<lambda>r. P (Some r)\<rbrace>"
using x f
apply (clarsimp simp: valid_def)
apply (drule_tac x=s in meta_spec; clarsimp)
apply (case_tac opt_x; simp)
done
{ fix y and h :: "'a \<Rightarrow> ('s,'d) nondet_monad"
have "do x \<leftarrow> f; _ \<leftarrow> g x y; h x od
= do x \<leftarrow> f; _ \<leftarrow> g x y; x \<leftarrow> f; h x od"
apply (rule ext)
apply (subst monad_eq_split[where g="do x \<leftarrow> f; g x y; return x od"
and P="\<top>" and Q="\<lambda>r. P (Some r)"
and f="h" and f'="\<lambda>_. f >>= h",
simplified bind_assoc, simplified])
apply (wpsimp wp: g f_rv simp: f return_def bind_def)+
done
} note f_redundant = this
show ?thesis
proof (cases "\<exists>s. P None s")
case True show ?thesis
apply (cases ys; simp add: True y mapM_x_Cons bind_assoc)
subgoal for y ys
apply (thin_tac _)
apply (induct ys arbitrary: y; simp add: mapM_x_Nil mapM_x_Cons bind_assoc)
apply (subst f_redundant; simp)
done
done
next
case False
show ?thesis using False
apply (induct ys; simp add: mapM_x_Nil mapM_x_Cons bind_assoc)
apply (rule ext)
subgoal for s
by (insert x[of s]; drule spec[of _ s]; clarsimp; case_tac opt_x;
clarsimp simp: bind_def return_def f)
apply (subst f_redundant; simp)
done
qed
qed
(* Move to DetSchedDomainTime_AI *)
crunch domain_list_inv[wp]: do_user_op "\<lambda>s. P (domain_list s)"
(wp: select_wp)
lemma next_child_child_set:
"\<lbrakk>next_child slot (cdt_list s) = Some child; valid_list s\<rbrakk>
\<Longrightarrow> child \<in> (case next_child slot (cdt_list s) of None \<Rightarrow> {} | Some n \<Rightarrow> {n})"
by (simp add: next_child_def)
lemma cap_delete_one_cur_tcb[wp]:
"\<lbrace>\<lambda>s. cur_tcb s\<rbrace> cap_delete_one slot \<lbrace>\<lambda>_ s. cur_tcb s\<rbrace>"
apply (simp add: cur_tcb_def)
apply (rule hoare_pre)
apply wps
apply wp
apply simp
done
lemma check_active_irq_invs:
"\<lbrace>invs and (ct_running or ct_idle) and einvs and (\<lambda>s. scheduler_action s = resume_cur_thread)
and (\<lambda>s. 0 < domain_time s) and valid_domain_list \<rbrace>
check_active_irq
\<lbrace>\<lambda>_. invs and (ct_running or ct_idle) and valid_list and valid_sched
and (\<lambda>s. scheduler_action s = resume_cur_thread)
and (\<lambda>s. 0 < domain_time s) and valid_domain_list \<rbrace>"
by (wpsimp simp: check_active_irq_def ct_in_state_def)
lemma check_active_irq_invs_just_running:
"\<lbrace>invs and ct_running and einvs and (\<lambda>s. scheduler_action s = resume_cur_thread)
and (\<lambda>s. 0 < domain_time s) and valid_domain_list \<rbrace>
check_active_irq
\<lbrace>\<lambda>_. invs and ct_running and valid_list and valid_sched
and (\<lambda>s. scheduler_action s = resume_cur_thread)
and (\<lambda>s. 0 < domain_time s) and valid_domain_list \<rbrace>"
by (wpsimp simp: check_active_irq_def ct_in_state_def)
lemma check_active_irq_invs_just_idle:
"\<lbrace>invs and ct_idle and einvs and (\<lambda>s. scheduler_action s = resume_cur_thread)
and (\<lambda>s. 0 < domain_time s) and valid_domain_list \<rbrace>
check_active_irq
\<lbrace>\<lambda>_. invs and ct_idle and valid_list and valid_sched
and (\<lambda>s. scheduler_action s = resume_cur_thread)
and (\<lambda>s. 0 < domain_time s) and valid_domain_list \<rbrace>"
by (wpsimp simp: check_active_irq_def ct_in_state_def)
end