|
1 (* |
|
2 ID: $Id$ |
|
3 Author: Jeremy Dawson and Gerwin Klein, NICTA |
|
4 |
|
5 contains theorems to do with shifting, rotating, splitting words |
|
6 *) |
|
7 |
|
8 theory WordShift imports WordBitwise begin |
|
9 |
|
10 section "Bit shifting" |
|
11 |
|
12 lemma shiftl1_number [simp] : |
|
13 "shiftl1 (number_of w) = number_of (w BIT bit.B0)" |
|
14 apply (unfold shiftl1_def word_number_of_def) |
|
15 apply (simp add: word_ubin.norm_eq_iff [symmetric] word_ubin.eq_norm) |
|
16 apply (subst refl [THEN bintrunc_BIT_I, symmetric]) |
|
17 apply (subst bintrunc_bintrunc_min) |
|
18 apply simp |
|
19 done |
|
20 |
|
21 lemma shiftl1_0 [simp] : "shiftl1 0 = 0" |
|
22 unfolding word_0_no shiftl1_number by auto |
|
23 |
|
24 lemmas shiftl1_def_u = shiftl1_def [folded word_number_of_def] |
|
25 |
|
26 lemma shiftl1_def_s: "shiftl1 w = number_of (sint w BIT bit.B0)" |
|
27 by (rule trans [OF _ shiftl1_number]) simp |
|
28 |
|
29 lemma shiftr1_0 [simp] : "shiftr1 0 = 0" |
|
30 unfolding shiftr1_def |
|
31 by simp (simp add: word_0_wi) |
|
32 |
|
33 lemma sshiftr1_0 [simp] : "sshiftr1 0 = 0" |
|
34 apply (unfold sshiftr1_def) |
|
35 apply simp |
|
36 apply (simp add : word_0_wi) |
|
37 done |
|
38 |
|
39 lemma sshiftr1_n1 [simp] : "sshiftr1 -1 = -1" |
|
40 unfolding sshiftr1_def by auto |
|
41 |
|
42 lemma shiftl_0 [simp] : "(0::'a::len0 word) << n = 0" |
|
43 unfolding shiftl_def by (induct n) auto |
|
44 |
|
45 lemma shiftr_0 [simp] : "(0::'a::len0 word) >> n = 0" |
|
46 unfolding shiftr_def by (induct n) auto |
|
47 |
|
48 lemma sshiftr_0 [simp] : "0 >>> n = 0" |
|
49 unfolding sshiftr_def by (induct n) auto |
|
50 |
|
51 lemma sshiftr_n1 [simp] : "-1 >>> n = -1" |
|
52 unfolding sshiftr_def by (induct n) auto |
|
53 |
|
54 lemma nth_shiftl1: "shiftl1 w !! n = (n < size w & n > 0 & w !! (n - 1))" |
|
55 apply (unfold shiftl1_def word_test_bit_def) |
|
56 apply (simp add: nth_bintr word_ubin.eq_norm word_size) |
|
57 apply (cases n) |
|
58 apply auto |
|
59 done |
|
60 |
|
61 lemma nth_shiftl' [rule_format]: |
|
62 "ALL n. ((w::'a::len0 word) << m) !! n = (n < size w & n >= m & w !! (n - m))" |
|
63 apply (unfold shiftl_def) |
|
64 apply (induct "m") |
|
65 apply (force elim!: test_bit_size) |
|
66 apply (clarsimp simp add : nth_shiftl1 word_size) |
|
67 apply arith |
|
68 done |
|
69 |
|
70 lemmas nth_shiftl = nth_shiftl' [unfolded word_size] |
|
71 |
|
72 lemma nth_shiftr1: "shiftr1 w !! n = w !! Suc n" |
|
73 apply (unfold shiftr1_def word_test_bit_def) |
|
74 apply (simp add: nth_bintr word_ubin.eq_norm) |
|
75 apply safe |
|
76 apply (drule bin_nth.Suc [THEN iffD2, THEN bin_nth_uint_imp]) |
|
77 apply simp |
|
78 done |
|
79 |
|
80 lemma nth_shiftr: |
|
81 "\<And>n. ((w::'a::len0 word) >> m) !! n = w !! (n + m)" |
|
82 apply (unfold shiftr_def) |
|
83 apply (induct "m") |
|
84 apply (auto simp add : nth_shiftr1) |
|
85 done |
|
86 |
|
87 (* see paper page 10, (1), (2), shiftr1_def is of the form of (1), |
|
88 where f (ie bin_rest) takes normal arguments to normal results, |
|
89 thus we get (2) from (1) *) |
|
90 |
|
91 lemma uint_shiftr1: "uint (shiftr1 w) = bin_rest (uint w)" |
|
92 apply (unfold shiftr1_def word_ubin.eq_norm bin_rest_trunc_i) |
|
93 apply (subst bintr_uint [symmetric, OF order_refl]) |
|
94 apply (simp only : bintrunc_bintrunc_l) |
|
95 apply simp |
|
96 done |
|
97 |
|
98 lemma nth_sshiftr1: |
|
99 "sshiftr1 w !! n = (if n = size w - 1 then w !! n else w !! Suc n)" |
|
100 apply (unfold sshiftr1_def word_test_bit_def) |
|
101 apply (simp add: nth_bintr word_ubin.eq_norm |
|
102 bin_nth.Suc [symmetric] word_size |
|
103 del: bin_nth.simps) |
|
104 apply (simp add: nth_bintr uint_sint del : bin_nth.simps) |
|
105 apply (auto simp add: bin_nth_sint) |
|
106 done |
|
107 |
|
108 lemma nth_sshiftr [rule_format] : |
|
109 "ALL n. sshiftr w m !! n = (n < size w & |
|
110 (if n + m >= size w then w !! (size w - 1) else w !! (n + m)))" |
|
111 apply (unfold sshiftr_def) |
|
112 apply (induct_tac "m") |
|
113 apply (simp add: test_bit_bl) |
|
114 apply (clarsimp simp add: nth_sshiftr1 word_size) |
|
115 apply safe |
|
116 apply arith |
|
117 apply arith |
|
118 apply (erule thin_rl) |
|
119 apply (case_tac n) |
|
120 apply safe |
|
121 apply simp |
|
122 apply simp |
|
123 apply (erule thin_rl) |
|
124 apply (case_tac n) |
|
125 apply safe |
|
126 apply simp |
|
127 apply simp |
|
128 apply arith+ |
|
129 done |
|
130 |
|
131 lemma shiftr1_div_2: "uint (shiftr1 w) = uint w div 2" |
|
132 apply (unfold shiftr1_def bin_rest_div) |
|
133 apply (rule word_uint.Abs_inverse) |
|
134 apply (simp add: uints_num pos_imp_zdiv_nonneg_iff) |
|
135 apply (rule xtr7) |
|
136 prefer 2 |
|
137 apply (rule zdiv_le_dividend) |
|
138 apply auto |
|
139 done |
|
140 |
|
141 lemma sshiftr1_div_2: "sint (sshiftr1 w) = sint w div 2" |
|
142 apply (unfold sshiftr1_def bin_rest_div [symmetric]) |
|
143 apply (simp add: word_sbin.eq_norm) |
|
144 apply (rule trans) |
|
145 defer |
|
146 apply (subst word_sbin.norm_Rep [symmetric]) |
|
147 apply (rule refl) |
|
148 apply (subst word_sbin.norm_Rep [symmetric]) |
|
149 apply (unfold One_nat_def) |
|
150 apply (rule sbintrunc_rest) |
|
151 done |
|
152 |
|
153 lemma shiftr_div_2n: "uint (shiftr w n) = uint w div 2 ^ n" |
|
154 apply (unfold shiftr_def) |
|
155 apply (induct "n") |
|
156 apply simp |
|
157 apply (simp add: shiftr1_div_2 mult_commute |
|
158 zdiv_zmult2_eq [symmetric]) |
|
159 done |
|
160 |
|
161 lemma sshiftr_div_2n: "sint (sshiftr w n) = sint w div 2 ^ n" |
|
162 apply (unfold sshiftr_def) |
|
163 apply (induct "n") |
|
164 apply simp |
|
165 apply (simp add: sshiftr1_div_2 mult_commute |
|
166 zdiv_zmult2_eq [symmetric]) |
|
167 done |
|
168 |
|
169 subsection "shift functions in terms of lists of bools" |
|
170 |
|
171 lemmas bshiftr1_no_bin [simp] = |
|
172 bshiftr1_def [where w="number_of ?w", unfolded to_bl_no_bin] |
|
173 |
|
174 lemma bshiftr1_bl: "to_bl (bshiftr1 b w) = b # butlast (to_bl w)" |
|
175 unfolding bshiftr1_def by (rule word_bl.Abs_inverse) simp |
|
176 |
|
177 lemma shiftl1_of_bl: "shiftl1 (of_bl bl) = of_bl (bl @ [False])" |
|
178 unfolding uint_bl of_bl_no |
|
179 by (simp add: bl_to_bin_aux_append bl_to_bin_def) |
|
180 |
|
181 lemmas shiftl1_bl = shiftl1_of_bl |
|
182 [where bl = "to_bl (?w :: ?'a :: len0 word)", simplified] |
|
183 |
|
184 lemma bl_shiftl1: |
|
185 "to_bl (shiftl1 (w :: 'a :: len word)) = tl (to_bl w) @ [False]" |
|
186 apply (simp add: shiftl1_bl word_rep_drop drop_Suc drop_Cons') |
|
187 apply (fast intro!: Suc_leI) |
|
188 done |
|
189 |
|
190 lemma shiftr1_bl: "shiftr1 w = of_bl (butlast (to_bl w))" |
|
191 apply (unfold shiftr1_def uint_bl of_bl_def) |
|
192 apply (simp add: butlast_rest_bin word_size) |
|
193 apply (simp add: bin_rest_trunc [symmetric, unfolded One_nat_def]) |
|
194 done |
|
195 |
|
196 lemma bl_shiftr1: |
|
197 "to_bl (shiftr1 (w :: 'a :: len word)) = False # butlast (to_bl w)" |
|
198 unfolding shiftr1_bl |
|
199 by (simp add : word_rep_drop len_gt_0 [THEN Suc_leI]) |
|
200 |
|
201 |
|
202 (* relate the two above : TODO - remove the :: len restriction on |
|
203 this theorem and others depending on it *) |
|
204 lemma shiftl1_rev: |
|
205 "shiftl1 (w :: 'a :: len word) = word_reverse (shiftr1 (word_reverse w))" |
|
206 apply (unfold word_reverse_def) |
|
207 apply (rule word_bl.Rep_inverse' [symmetric]) |
|
208 apply (simp add: bl_shiftl1 bl_shiftr1 word_bl.Abs_inverse) |
|
209 apply (cases "to_bl w") |
|
210 apply auto |
|
211 done |
|
212 |
|
213 lemma shiftl_rev: |
|
214 "shiftl (w :: 'a :: len word) n = word_reverse (shiftr (word_reverse w) n)" |
|
215 apply (unfold shiftl_def shiftr_def) |
|
216 apply (induct "n") |
|
217 apply (auto simp add : shiftl1_rev) |
|
218 done |
|
219 |
|
220 lemmas rev_shiftl = |
|
221 shiftl_rev [where w = "word_reverse ?w1", simplified, standard] |
|
222 |
|
223 lemmas shiftr_rev = rev_shiftl [THEN word_rev_gal', standard] |
|
224 lemmas rev_shiftr = shiftl_rev [THEN word_rev_gal', standard] |
|
225 |
|
226 lemma bl_sshiftr1: |
|
227 "to_bl (sshiftr1 (w :: 'a :: len word)) = hd (to_bl w) # butlast (to_bl w)" |
|
228 apply (unfold sshiftr1_def uint_bl word_size) |
|
229 apply (simp add: butlast_rest_bin word_ubin.eq_norm) |
|
230 apply (simp add: sint_uint) |
|
231 apply (rule nth_equalityI) |
|
232 apply clarsimp |
|
233 apply clarsimp |
|
234 apply (case_tac i) |
|
235 apply (simp_all add: hd_conv_nth length_0_conv [symmetric] |
|
236 nth_bin_to_bl bin_nth.Suc [symmetric] |
|
237 nth_sbintr |
|
238 del: bin_nth.Suc) |
|
239 apply force |
|
240 apply (rule impI) |
|
241 apply (rule_tac f = "bin_nth (uint w)" in arg_cong) |
|
242 apply simp |
|
243 done |
|
244 |
|
245 lemma drop_shiftr: |
|
246 "drop n (to_bl ((w :: 'a :: len word) >> n)) = take (size w - n) (to_bl w)" |
|
247 apply (unfold shiftr_def) |
|
248 apply (induct n) |
|
249 prefer 2 |
|
250 apply (simp add: drop_Suc bl_shiftr1 butlast_drop [symmetric]) |
|
251 apply (rule butlast_take [THEN trans]) |
|
252 apply (auto simp: word_size) |
|
253 done |
|
254 |
|
255 lemma drop_sshiftr: |
|
256 "drop n (to_bl ((w :: 'a :: len word) >>> n)) = take (size w - n) (to_bl w)" |
|
257 apply (unfold sshiftr_def) |
|
258 apply (induct n) |
|
259 prefer 2 |
|
260 apply (simp add: drop_Suc bl_sshiftr1 butlast_drop [symmetric]) |
|
261 apply (rule butlast_take [THEN trans]) |
|
262 apply (auto simp: word_size) |
|
263 done |
|
264 |
|
265 lemma take_shiftr [rule_format] : |
|
266 "n <= size (w :: 'a :: len word) --> take n (to_bl (w >> n)) = |
|
267 replicate n False" |
|
268 apply (unfold shiftr_def) |
|
269 apply (induct n) |
|
270 prefer 2 |
|
271 apply (simp add: bl_shiftr1) |
|
272 apply (rule impI) |
|
273 apply (rule take_butlast [THEN trans]) |
|
274 apply (auto simp: word_size) |
|
275 done |
|
276 |
|
277 lemma take_sshiftr' [rule_format] : |
|
278 "n <= size (w :: 'a :: len word) --> hd (to_bl (w >>> n)) = hd (to_bl w) & |
|
279 take n (to_bl (w >>> n)) = replicate n (hd (to_bl w))" |
|
280 apply (unfold sshiftr_def) |
|
281 apply (induct n) |
|
282 prefer 2 |
|
283 apply (simp add: bl_sshiftr1) |
|
284 apply (rule impI) |
|
285 apply (rule take_butlast [THEN trans]) |
|
286 apply (auto simp: word_size) |
|
287 done |
|
288 |
|
289 lemmas hd_sshiftr = take_sshiftr' [THEN conjunct1, standard] |
|
290 lemmas take_sshiftr = take_sshiftr' [THEN conjunct2, standard] |
|
291 |
|
292 lemma atd_lem: "take n xs = t ==> drop n xs = d ==> xs = t @ d" |
|
293 by (auto intro: append_take_drop_id [symmetric]) |
|
294 |
|
295 lemmas bl_shiftr = atd_lem [OF take_shiftr drop_shiftr] |
|
296 lemmas bl_sshiftr = atd_lem [OF take_sshiftr drop_sshiftr] |
|
297 |
|
298 lemma shiftl_of_bl: "of_bl bl << n = of_bl (bl @ replicate n False)" |
|
299 unfolding shiftl_def |
|
300 by (induct n) (auto simp: shiftl1_of_bl replicate_app_Cons_same) |
|
301 |
|
302 lemmas shiftl_bl = |
|
303 shiftl_of_bl [where bl = "to_bl (?w :: ?'a :: len0 word)", simplified] |
|
304 |
|
305 lemmas shiftl_number [simp] = shiftl_def [where w="number_of ?w"] |
|
306 |
|
307 lemma bl_shiftl: |
|
308 "to_bl (w << n) = drop n (to_bl w) @ replicate (min (size w) n) False" |
|
309 by (simp add: shiftl_bl word_rep_drop word_size min_def) |
|
310 |
|
311 lemma shiftl_zero_size: |
|
312 fixes x :: "'a::len0 word" |
|
313 shows "size x <= n ==> x << n = 0" |
|
314 apply (unfold word_size) |
|
315 apply (rule word_eqI) |
|
316 apply (clarsimp simp add: shiftl_bl word_size test_bit_of_bl nth_append) |
|
317 done |
|
318 |
|
319 (* note - the following results use 'a :: len word < number_ring *) |
|
320 |
|
321 lemma shiftl1_2t: "shiftl1 (w :: 'a :: len word) = 2 * w" |
|
322 apply (simp add: shiftl1_def_u) |
|
323 apply (simp only: double_number_of_BIT [symmetric]) |
|
324 apply simp |
|
325 done |
|
326 |
|
327 lemma shiftl1_p: "shiftl1 (w :: 'a :: len word) = w + w" |
|
328 apply (simp add: shiftl1_def_u) |
|
329 apply (simp only: double_number_of_BIT [symmetric]) |
|
330 apply simp |
|
331 done |
|
332 |
|
333 lemma shiftl_t2n: "shiftl (w :: 'a :: len word) n = 2 ^ n * w" |
|
334 unfolding shiftl_def |
|
335 by (induct n) (auto simp: shiftl1_2t power_Suc) |
|
336 |
|
337 lemma shiftr1_bintr [simp]: |
|
338 "(shiftr1 (number_of w) :: 'a :: len0 word) = |
|
339 number_of (bin_rest (bintrunc (len_of TYPE ('a)) w))" |
|
340 unfolding shiftr1_def word_number_of_def |
|
341 by (simp add : word_ubin.eq_norm) |
|
342 |
|
343 lemma sshiftr1_sbintr [simp] : |
|
344 "(sshiftr1 (number_of w) :: 'a :: len word) = |
|
345 number_of (bin_rest (sbintrunc (len_of TYPE ('a) - 1) w))" |
|
346 unfolding sshiftr1_def word_number_of_def |
|
347 by (simp add : word_sbin.eq_norm) |
|
348 |
|
349 lemma shiftr_no': |
|
350 "w = number_of bin ==> |
|
351 (w::'a::len0 word) >> n = number_of ((bin_rest ^ n) (bintrunc (size w) bin))" |
|
352 apply clarsimp |
|
353 apply (rule word_eqI) |
|
354 apply (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size) |
|
355 done |
|
356 |
|
357 lemma sshiftr_no': |
|
358 "w = number_of bin ==> w >>> n = number_of ((bin_rest ^ n) |
|
359 (sbintrunc (size w - 1) bin))" |
|
360 apply clarsimp |
|
361 apply (rule word_eqI) |
|
362 apply (auto simp: nth_sshiftr nth_rest_power_bin nth_sbintr word_size) |
|
363 apply (subgoal_tac "na + n = len_of TYPE('a) - Suc 0", simp, simp)+ |
|
364 done |
|
365 |
|
366 lemmas sshiftr_no [simp] = |
|
367 sshiftr_no' [where w = "number_of ?w", OF refl, unfolded word_size] |
|
368 |
|
369 lemmas shiftr_no [simp] = |
|
370 shiftr_no' [where w = "number_of ?w", OF refl, unfolded word_size] |
|
371 |
|
372 lemma shiftr1_bl_of': |
|
373 "us = shiftr1 (of_bl bl) ==> length bl <= size us ==> |
|
374 us = of_bl (butlast bl)" |
|
375 by (clarsimp simp: shiftr1_def of_bl_def word_size butlast_rest_bl2bin |
|
376 word_ubin.eq_norm trunc_bl2bin) |
|
377 |
|
378 lemmas shiftr1_bl_of = refl [THEN shiftr1_bl_of', unfolded word_size] |
|
379 |
|
380 lemma shiftr_bl_of' [rule_format]: |
|
381 "us = of_bl bl >> n ==> length bl <= size us --> |
|
382 us = of_bl (take (length bl - n) bl)" |
|
383 apply (unfold shiftr_def) |
|
384 apply hypsubst |
|
385 apply (unfold word_size) |
|
386 apply (induct n) |
|
387 apply clarsimp |
|
388 apply clarsimp |
|
389 apply (subst shiftr1_bl_of) |
|
390 apply simp |
|
391 apply (simp add: butlast_take) |
|
392 done |
|
393 |
|
394 lemmas shiftr_bl_of = refl [THEN shiftr_bl_of', unfolded word_size] |
|
395 |
|
396 lemmas shiftr_bl = word_bl.Rep' [THEN eq_imp_le, THEN shiftr_bl_of, |
|
397 simplified word_size, simplified, THEN eq_reflection, standard] |
|
398 |
|
399 lemma msb_shift': "msb (w::'a::len word) <-> (w >> (size w - 1)) ~= 0" |
|
400 apply (unfold shiftr_bl word_msb_alt) |
|
401 apply (simp add: word_size Suc_le_eq take_Suc) |
|
402 apply (cases "hd (to_bl w)") |
|
403 apply (auto simp: word_1_bl word_0_bl |
|
404 of_bl_rep_False [where n=1 and bs="[]", simplified]) |
|
405 done |
|
406 |
|
407 lemmas msb_shift = msb_shift' [unfolded word_size] |
|
408 |
|
409 lemma align_lem_or [rule_format] : |
|
410 "ALL x m. length x = n + m --> length y = n + m --> |
|
411 drop m x = replicate n False --> take m y = replicate m False --> |
|
412 app2 op | x y = take m x @ drop m y" |
|
413 apply (induct_tac y) |
|
414 apply force |
|
415 apply clarsimp |
|
416 apply (case_tac x, force) |
|
417 apply (case_tac m, auto) |
|
418 apply (drule sym) |
|
419 apply auto |
|
420 apply (induct_tac list, auto) |
|
421 done |
|
422 |
|
423 lemma align_lem_and [rule_format] : |
|
424 "ALL x m. length x = n + m --> length y = n + m --> |
|
425 drop m x = replicate n False --> take m y = replicate m False --> |
|
426 app2 op & x y = replicate (n + m) False" |
|
427 apply (induct_tac y) |
|
428 apply force |
|
429 apply clarsimp |
|
430 apply (case_tac x, force) |
|
431 apply (case_tac m, auto) |
|
432 apply (drule sym) |
|
433 apply auto |
|
434 apply (induct_tac list, auto) |
|
435 done |
|
436 |
|
437 lemma aligned_bl_add_size': |
|
438 "size x - n = m ==> n <= size x ==> drop m (to_bl x) = replicate n False ==> |
|
439 take m (to_bl y) = replicate m False ==> |
|
440 to_bl (x + y) = take m (to_bl x) @ drop m (to_bl y)" |
|
441 apply (subgoal_tac "x AND y = 0") |
|
442 prefer 2 |
|
443 apply (rule word_bl.Rep_eqD) |
|
444 apply (simp add: bl_word_and to_bl_0) |
|
445 apply (rule align_lem_and [THEN trans]) |
|
446 apply (simp_all add: word_size)[5] |
|
447 apply (rule_tac f = "%n. replicate n False" in arg_cong) |
|
448 apply simp |
|
449 apply (subst word_plus_and_or [symmetric]) |
|
450 apply (simp add : bl_word_or) |
|
451 apply (rule align_lem_or) |
|
452 apply (simp_all add: word_size) |
|
453 done |
|
454 |
|
455 lemmas aligned_bl_add_size = refl [THEN aligned_bl_add_size'] |
|
456 |
|
457 subsection "Mask" |
|
458 |
|
459 lemma nth_mask': "m = mask n ==> test_bit m i = (i < n & i < size m)" |
|
460 apply (unfold mask_def test_bit_bl) |
|
461 apply (simp only: word_1_bl [symmetric] shiftl_of_bl) |
|
462 apply (clarsimp simp add: word_size) |
|
463 apply (simp only: of_bl_no mask_lem number_of_succ add_diff_cancel2) |
|
464 apply (fold of_bl_no) |
|
465 apply (simp add: word_1_bl) |
|
466 apply (rule test_bit_of_bl [THEN trans, unfolded test_bit_bl word_size]) |
|
467 apply auto |
|
468 done |
|
469 |
|
470 lemmas nth_mask [simp] = refl [THEN nth_mask'] |
|
471 |
|
472 lemma mask_bl: "mask n = of_bl (replicate n True)" |
|
473 by (auto simp add : test_bit_of_bl word_size intro: word_eqI) |
|
474 |
|
475 lemma mask_bin: "mask n = number_of (bintrunc n Numeral.Min)" |
|
476 by (auto simp add: nth_bintr word_size intro: word_eqI) |
|
477 |
|
478 lemma and_mask_bintr: "w AND mask n = number_of (bintrunc n (uint w))" |
|
479 apply (rule word_eqI) |
|
480 apply (simp add: nth_bintr word_size word_ops_nth_size) |
|
481 apply (auto simp add: test_bit_bin) |
|
482 done |
|
483 |
|
484 lemma and_mask_no: "number_of i AND mask n = number_of (bintrunc n i)" |
|
485 by (auto simp add : nth_bintr word_size word_ops_nth_size intro: word_eqI) |
|
486 |
|
487 lemmas and_mask_wi = and_mask_no [unfolded word_number_of_def] |
|
488 |
|
489 lemma bl_and_mask: |
|
490 "to_bl (w AND mask n :: 'a :: len word) = |
|
491 replicate (len_of TYPE('a) - n) False @ |
|
492 drop (len_of TYPE('a) - n) (to_bl w)" |
|
493 apply (rule nth_equalityI) |
|
494 apply simp |
|
495 apply (clarsimp simp add: to_bl_nth word_size) |
|
496 apply (simp add: word_size word_ops_nth_size) |
|
497 apply (auto simp add: word_size test_bit_bl nth_append nth_rev) |
|
498 done |
|
499 |
|
500 lemmas and_mask_mod_2p = |
|
501 and_mask_bintr [unfolded word_number_of_alt no_bintr_alt] |
|
502 |
|
503 lemma and_mask_lt_2p: "uint (w AND mask n) < 2 ^ n" |
|
504 apply (simp add : and_mask_bintr no_bintr_alt) |
|
505 apply (rule xtr8) |
|
506 prefer 2 |
|
507 apply (rule pos_mod_bound) |
|
508 apply auto |
|
509 done |
|
510 |
|
511 lemmas eq_mod_iff = trans [symmetric, OF int_mod_lem eq_sym_conv] |
|
512 |
|
513 lemma mask_eq_iff: "(w AND mask n) = w <-> uint w < 2 ^ n" |
|
514 apply (simp add: and_mask_bintr word_number_of_def) |
|
515 apply (simp add: word_ubin.inverse_norm) |
|
516 apply (simp add: eq_mod_iff bintrunc_mod2p min_def) |
|
517 apply (fast intro!: lt2p_lem) |
|
518 done |
|
519 |
|
520 lemma and_mask_dvd: "2 ^ n dvd uint w = (w AND mask n = 0)" |
|
521 apply (simp add: zdvd_iff_zmod_eq_0 and_mask_mod_2p) |
|
522 apply (simp add: word_uint.norm_eq_iff [symmetric] word_of_int_homs) |
|
523 apply (subst word_uint.norm_Rep [symmetric]) |
|
524 apply (simp only: bintrunc_bintrunc_min bintrunc_mod2p [symmetric] min_def) |
|
525 apply auto |
|
526 done |
|
527 |
|
528 lemma and_mask_dvd_nat: "2 ^ n dvd unat w = (w AND mask n = 0)" |
|
529 apply (unfold unat_def) |
|
530 apply (rule trans [OF _ and_mask_dvd]) |
|
531 apply (unfold dvd_def) |
|
532 apply auto |
|
533 apply (drule uint_ge_0 [THEN nat_int.Abs_inverse' [simplified], symmetric]) |
|
534 apply (simp add : int_mult int_power) |
|
535 apply (simp add : nat_mult_distrib nat_power_eq) |
|
536 done |
|
537 |
|
538 lemma word_2p_lem: |
|
539 "n < size w ==> w < 2 ^ n = (uint (w :: 'a :: len word) < 2 ^ n)" |
|
540 apply (unfold word_size word_less_alt word_number_of_alt) |
|
541 apply (clarsimp simp add: word_of_int_power_hom word_uint.eq_norm |
|
542 int_mod_eq' |
|
543 simp del: word_of_int_bin) |
|
544 done |
|
545 |
|
546 lemma less_mask_eq: "x < 2 ^ n ==> x AND mask n = (x :: 'a :: len word)" |
|
547 apply (unfold word_less_alt word_number_of_alt) |
|
548 apply (clarsimp simp add: and_mask_mod_2p word_of_int_power_hom |
|
549 word_uint.eq_norm |
|
550 simp del: word_of_int_bin) |
|
551 apply (drule xtr8 [rotated]) |
|
552 apply (rule int_mod_le) |
|
553 apply (auto simp add : mod_pos_pos_trivial) |
|
554 done |
|
555 |
|
556 lemmas mask_eq_iff_w2p = |
|
557 trans [OF mask_eq_iff word_2p_lem [symmetric], standard] |
|
558 |
|
559 lemmas and_mask_less' = |
|
560 iffD2 [OF word_2p_lem and_mask_lt_2p, simplified word_size, standard] |
|
561 |
|
562 lemma and_mask_less_size: "n < size x ==> x AND mask n < 2^n" |
|
563 unfolding word_size by (erule and_mask_less') |
|
564 |
|
565 lemma word_mod_2p_is_mask': |
|
566 "c = 2 ^ n ==> c > 0 ==> x mod c = (x :: 'a :: len word) AND mask n" |
|
567 by (clarsimp simp add: word_mod_def uint_2p and_mask_mod_2p) |
|
568 |
|
569 lemmas word_mod_2p_is_mask = refl [THEN word_mod_2p_is_mask'] |
|
570 |
|
571 lemma mask_eqs: |
|
572 "(a AND mask n) + b AND mask n = a + b AND mask n" |
|
573 "a + (b AND mask n) AND mask n = a + b AND mask n" |
|
574 "(a AND mask n) - b AND mask n = a - b AND mask n" |
|
575 "a - (b AND mask n) AND mask n = a - b AND mask n" |
|
576 "a * (b AND mask n) AND mask n = a * b AND mask n" |
|
577 "(b AND mask n) * a AND mask n = b * a AND mask n" |
|
578 "(a AND mask n) + (b AND mask n) AND mask n = a + b AND mask n" |
|
579 "(a AND mask n) - (b AND mask n) AND mask n = a - b AND mask n" |
|
580 "(a AND mask n) * (b AND mask n) AND mask n = a * b AND mask n" |
|
581 "- (a AND mask n) AND mask n = - a AND mask n" |
|
582 "word_succ (a AND mask n) AND mask n = word_succ a AND mask n" |
|
583 "word_pred (a AND mask n) AND mask n = word_pred a AND mask n" |
|
584 using word_of_int_Ex [where x=a] word_of_int_Ex [where x=b] |
|
585 by (auto simp: and_mask_wi bintr_ariths bintr_arith1s new_word_of_int_homs) |
|
586 |
|
587 lemma mask_power_eq: |
|
588 "(x AND mask n) ^ k AND mask n = x ^ k AND mask n" |
|
589 using word_of_int_Ex [where x=x] |
|
590 by (clarsimp simp: and_mask_wi word_of_int_power_hom bintr_ariths) |
|
591 |
|
592 |
|
593 subsection "Revcast" |
|
594 |
|
595 lemmas revcast_def' = revcast_def [simplified] |
|
596 lemmas revcast_def'' = revcast_def' [simplified word_size] |
|
597 lemmas revcast_no_def [simp] = |
|
598 revcast_def' [where w="number_of ?w", unfolded word_size] |
|
599 |
|
600 lemma to_bl_revcast: |
|
601 "to_bl (revcast w :: 'a :: len0 word) = |
|
602 takefill False (len_of TYPE ('a)) (to_bl w)" |
|
603 apply (unfold revcast_def' word_size) |
|
604 apply (rule word_bl.Abs_inverse) |
|
605 apply simp |
|
606 done |
|
607 |
|
608 lemma revcast_rev_ucast': |
|
609 "cs = [rc, uc] ==> rc = revcast (word_reverse w) ==> uc = ucast w ==> |
|
610 rc = word_reverse uc" |
|
611 apply (unfold ucast_def revcast_def' Let_def word_reverse_def) |
|
612 apply (clarsimp simp add : to_bl_of_bin takefill_bintrunc) |
|
613 apply (simp add : word_bl.Abs_inverse word_size) |
|
614 done |
|
615 |
|
616 lemmas revcast_rev_ucast = revcast_rev_ucast' [OF refl refl refl] |
|
617 |
|
618 lemmas revcast_ucast = revcast_rev_ucast |
|
619 [where w = "word_reverse ?w1", simplified word_rev_rev, standard] |
|
620 |
|
621 lemmas ucast_revcast = revcast_rev_ucast [THEN word_rev_gal', standard] |
|
622 lemmas ucast_rev_revcast = revcast_ucast [THEN word_rev_gal', standard] |
|
623 |
|
624 |
|
625 -- "linking revcast and cast via shift" |
|
626 |
|
627 lemmas wsst_TYs = source_size target_size word_size |
|
628 |
|
629 lemma revcast_down_uu': |
|
630 "rc = revcast ==> source_size rc = target_size rc + n ==> |
|
631 rc (w :: 'a :: len word) = ucast (w >> n)" |
|
632 apply (simp add: revcast_def') |
|
633 apply (rule word_bl.Rep_inverse') |
|
634 apply (rule trans, rule ucast_down_drop) |
|
635 prefer 2 |
|
636 apply (rule trans, rule drop_shiftr) |
|
637 apply (auto simp: takefill_alt wsst_TYs) |
|
638 done |
|
639 |
|
640 lemma revcast_down_us': |
|
641 "rc = revcast ==> source_size rc = target_size rc + n ==> |
|
642 rc (w :: 'a :: len word) = ucast (w >>> n)" |
|
643 apply (simp add: revcast_def') |
|
644 apply (rule word_bl.Rep_inverse') |
|
645 apply (rule trans, rule ucast_down_drop) |
|
646 prefer 2 |
|
647 apply (rule trans, rule drop_sshiftr) |
|
648 apply (auto simp: takefill_alt wsst_TYs) |
|
649 done |
|
650 |
|
651 lemma revcast_down_su': |
|
652 "rc = revcast ==> source_size rc = target_size rc + n ==> |
|
653 rc (w :: 'a :: len word) = scast (w >> n)" |
|
654 apply (simp add: revcast_def') |
|
655 apply (rule word_bl.Rep_inverse') |
|
656 apply (rule trans, rule scast_down_drop) |
|
657 prefer 2 |
|
658 apply (rule trans, rule drop_shiftr) |
|
659 apply (auto simp: takefill_alt wsst_TYs) |
|
660 done |
|
661 |
|
662 lemma revcast_down_ss': |
|
663 "rc = revcast ==> source_size rc = target_size rc + n ==> |
|
664 rc (w :: 'a :: len word) = scast (w >>> n)" |
|
665 apply (simp add: revcast_def') |
|
666 apply (rule word_bl.Rep_inverse') |
|
667 apply (rule trans, rule scast_down_drop) |
|
668 prefer 2 |
|
669 apply (rule trans, rule drop_sshiftr) |
|
670 apply (auto simp: takefill_alt wsst_TYs) |
|
671 done |
|
672 |
|
673 lemmas revcast_down_uu = refl [THEN revcast_down_uu'] |
|
674 lemmas revcast_down_us = refl [THEN revcast_down_us'] |
|
675 lemmas revcast_down_su = refl [THEN revcast_down_su'] |
|
676 lemmas revcast_down_ss = refl [THEN revcast_down_ss'] |
|
677 |
|
678 lemma cast_down_rev: |
|
679 "uc = ucast ==> source_size uc = target_size uc + n ==> |
|
680 uc w = revcast ((w :: 'a :: len word) << n)" |
|
681 apply (unfold shiftl_rev) |
|
682 apply clarify |
|
683 apply (simp add: revcast_rev_ucast) |
|
684 apply (rule word_rev_gal') |
|
685 apply (rule trans [OF _ revcast_rev_ucast]) |
|
686 apply (rule revcast_down_uu [symmetric]) |
|
687 apply (auto simp add: wsst_TYs) |
|
688 done |
|
689 |
|
690 lemma revcast_up': |
|
691 "rc = revcast ==> source_size rc + n = target_size rc ==> |
|
692 rc w = (ucast w :: 'a :: len word) << n" |
|
693 apply (simp add: revcast_def') |
|
694 apply (rule word_bl.Rep_inverse') |
|
695 apply (simp add: takefill_alt) |
|
696 apply (rule bl_shiftl [THEN trans]) |
|
697 apply (subst ucast_up_app) |
|
698 apply (auto simp add: wsst_TYs) |
|
699 apply (drule sym) |
|
700 apply (simp add: min_def) |
|
701 done |
|
702 |
|
703 lemmas revcast_up = refl [THEN revcast_up'] |
|
704 |
|
705 lemmas rc1 = revcast_up [THEN |
|
706 revcast_rev_ucast [symmetric, THEN trans, THEN word_rev_gal, symmetric]] |
|
707 lemmas rc2 = revcast_down_uu [THEN |
|
708 revcast_rev_ucast [symmetric, THEN trans, THEN word_rev_gal, symmetric]] |
|
709 |
|
710 lemmas ucast_up = |
|
711 rc1 [simplified rev_shiftr [symmetric] revcast_ucast [symmetric]] |
|
712 lemmas ucast_down = |
|
713 rc2 [simplified rev_shiftr revcast_ucast [symmetric]] |
|
714 |
|
715 |
|
716 subsection "Slices" |
|
717 |
|
718 lemmas slice1_no_bin [simp] = |
|
719 slice1_def [where w="number_of ?w", unfolded to_bl_no_bin] |
|
720 |
|
721 lemmas slice_no_bin [simp] = |
|
722 trans [OF slice_def [THEN meta_eq_to_obj_eq] |
|
723 slice1_no_bin [THEN meta_eq_to_obj_eq], |
|
724 unfolded word_size, standard] |
|
725 |
|
726 lemma slice1_0 [simp] : "slice1 n 0 = 0" |
|
727 unfolding slice1_def by (simp add : to_bl_0) |
|
728 |
|
729 lemma slice_0 [simp] : "slice n 0 = 0" |
|
730 unfolding slice_def by auto |
|
731 |
|
732 lemma slice_take': "slice n w = of_bl (take (size w - n) (to_bl w))" |
|
733 unfolding slice_def' slice1_def |
|
734 by (simp add : takefill_alt word_size) |
|
735 |
|
736 lemmas slice_take = slice_take' [unfolded word_size] |
|
737 |
|
738 -- "shiftr to a word of the same size is just slice, |
|
739 slice is just shiftr then ucast" |
|
740 lemmas shiftr_slice = trans |
|
741 [OF shiftr_bl [THEN meta_eq_to_obj_eq] slice_take [symmetric], standard] |
|
742 |
|
743 lemma slice_shiftr: "slice n w = ucast (w >> n)" |
|
744 apply (unfold slice_take shiftr_bl) |
|
745 apply (rule ucast_of_bl_up [symmetric]) |
|
746 apply (simp add: word_size) |
|
747 done |
|
748 |
|
749 lemma nth_slice: |
|
750 "(slice n w :: 'a :: len0 word) !! m = |
|
751 (w !! (m + n) & m < len_of TYPE ('a))" |
|
752 unfolding slice_shiftr |
|
753 by (simp add : nth_ucast nth_shiftr) |
|
754 |
|
755 lemma slice1_down_alt': |
|
756 "sl = slice1 n w ==> fs = size sl ==> fs + k = n ==> |
|
757 to_bl sl = takefill False fs (drop k (to_bl w))" |
|
758 unfolding slice1_def word_size of_bl_def uint_bl |
|
759 by (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop drop_takefill) |
|
760 |
|
761 lemma slice1_up_alt': |
|
762 "sl = slice1 n w ==> fs = size sl ==> fs = n + k ==> |
|
763 to_bl sl = takefill False fs (replicate k False @ (to_bl w))" |
|
764 apply (unfold slice1_def word_size of_bl_def uint_bl) |
|
765 apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop |
|
766 takefill_append [symmetric]) |
|
767 apply (rule_tac f = "%k. takefill False (len_of TYPE('a)) |
|
768 (replicate k False @ bin_to_bl (len_of TYPE('b)) (uint w))" in arg_cong) |
|
769 apply arith |
|
770 done |
|
771 |
|
772 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size] |
|
773 lemmas su1 = slice1_up_alt' [OF refl refl, unfolded word_size] |
|
774 lemmas slice1_down_alt = le_add_diff_inverse [THEN sd1] |
|
775 lemmas slice1_up_alts = |
|
776 le_add_diff_inverse [symmetric, THEN su1] |
|
777 le_add_diff_inverse2 [symmetric, THEN su1] |
|
778 |
|
779 lemma ucast_slice1: "ucast w = slice1 (size w) w" |
|
780 unfolding slice1_def ucast_bl |
|
781 by (simp add : takefill_same' word_size) |
|
782 |
|
783 lemma ucast_slice: "ucast w = slice 0 w" |
|
784 unfolding slice_def by (simp add : ucast_slice1) |
|
785 |
|
786 lemmas slice_id = trans [OF ucast_slice [symmetric] ucast_id] |
|
787 |
|
788 lemma revcast_slice1': |
|
789 "rc = revcast w ==> slice1 (size rc) w = rc" |
|
790 unfolding slice1_def revcast_def' by (simp add : word_size) |
|
791 |
|
792 lemmas revcast_slice1 = refl [THEN revcast_slice1'] |
|
793 |
|
794 lemma slice1_tf_tf': |
|
795 "to_bl (slice1 n w :: 'a :: len0 word) = |
|
796 rev (takefill False (len_of TYPE('a)) (rev (takefill False n (to_bl w))))" |
|
797 unfolding slice1_def by (rule word_rev_tf) |
|
798 |
|
799 lemmas slice1_tf_tf = slice1_tf_tf' |
|
800 [THEN word_bl.Rep_inverse', symmetric, standard] |
|
801 |
|
802 lemma rev_slice1: |
|
803 "n + k = len_of TYPE('a) + len_of TYPE('b) \<Longrightarrow> |
|
804 slice1 n (word_reverse w :: 'b :: len0 word) = |
|
805 word_reverse (slice1 k w :: 'a :: len0 word)" |
|
806 apply (unfold word_reverse_def slice1_tf_tf) |
|
807 apply (rule word_bl.Rep_inverse') |
|
808 apply (rule rev_swap [THEN iffD1]) |
|
809 apply (rule trans [symmetric]) |
|
810 apply (rule tf_rev) |
|
811 apply (simp add: word_bl.Abs_inverse) |
|
812 apply (simp add: word_bl.Abs_inverse) |
|
813 done |
|
814 |
|
815 lemma rev_slice': |
|
816 "res = slice n (word_reverse w) ==> n + k + size res = size w ==> |
|
817 res = word_reverse (slice k w)" |
|
818 apply (unfold slice_def word_size) |
|
819 apply clarify |
|
820 apply (rule rev_slice1) |
|
821 apply arith |
|
822 done |
|
823 |
|
824 lemmas rev_slice = refl [THEN rev_slice', unfolded word_size] |
|
825 |
|
826 lemmas sym_notr = |
|
827 not_iff [THEN iffD2, THEN not_sym, THEN not_iff [THEN iffD1]] |
|
828 |
|
829 -- {* problem posed by TPHOLs referee: |
|
830 criterion for overflow of addition of signed integers *} |
|
831 |
|
832 lemma sofl_test: |
|
833 "(sint (x :: 'a :: len word) + sint y = sint (x + y)) = |
|
834 ((((x+y) XOR x) AND ((x+y) XOR y)) >> (size x - 1) = 0)" |
|
835 apply (unfold word_size) |
|
836 apply (cases "len_of TYPE('a)", simp) |
|
837 apply (subst msb_shift [THEN sym_notr]) |
|
838 apply (simp add: word_ops_msb) |
|
839 apply (simp add: word_msb_sint) |
|
840 apply safe |
|
841 apply simp_all |
|
842 apply (unfold sint_word_ariths) |
|
843 apply (unfold word_sbin.set_iff_norm [symmetric] sints_num) |
|
844 apply safe |
|
845 apply (insert sint_range' [where x=x]) |
|
846 apply (insert sint_range' [where x=y]) |
|
847 defer |
|
848 apply (simp (no_asm), arith) |
|
849 apply (simp (no_asm), arith) |
|
850 defer |
|
851 defer |
|
852 apply (simp (no_asm), arith) |
|
853 apply (simp (no_asm), arith) |
|
854 apply (rule notI [THEN notnotD], |
|
855 drule leI not_leE, |
|
856 drule sbintrunc_inc sbintrunc_dec, |
|
857 simp)+ |
|
858 done |
|
859 |
|
860 |
|
861 section "Split and cat" |
|
862 |
|
863 lemmas word_split_bin' = word_split_def [THEN meta_eq_to_obj_eq, standard] |
|
864 lemmas word_cat_bin' = word_cat_def [THEN meta_eq_to_obj_eq, standard] |
|
865 |
|
866 lemma word_rsplit_no: |
|
867 "(word_rsplit (number_of bin :: 'b :: len0 word) :: 'a word list) = |
|
868 map number_of (bin_rsplit (len_of TYPE('a :: len)) |
|
869 (len_of TYPE('b), bintrunc (len_of TYPE('b)) bin))" |
|
870 apply (unfold word_rsplit_def word_no_wi) |
|
871 apply (simp add: word_ubin.eq_norm) |
|
872 done |
|
873 |
|
874 lemmas word_rsplit_no_cl [simp] = word_rsplit_no |
|
875 [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]] |
|
876 |
|
877 lemma test_bit_cat: |
|
878 "wc = word_cat a b ==> wc !! n = (n < size wc & |
|
879 (if n < size b then b !! n else a !! (n - size b)))" |
|
880 apply (unfold word_cat_bin' test_bit_bin) |
|
881 apply (auto simp add : word_ubin.eq_norm nth_bintr bin_nth_cat word_size) |
|
882 apply (erule bin_nth_uint_imp) |
|
883 done |
|
884 |
|
885 lemma word_cat_bl: "word_cat a b = of_bl (to_bl a @ to_bl b)" |
|
886 apply (unfold of_bl_def to_bl_def word_cat_bin') |
|
887 apply (simp add: bl_to_bin_app_cat) |
|
888 done |
|
889 |
|
890 lemma of_bl_append: |
|
891 "(of_bl (xs @ ys) :: 'a :: len word) = of_bl xs * 2^(length ys) + of_bl ys" |
|
892 apply (unfold of_bl_def) |
|
893 apply (simp add: bl_to_bin_app_cat bin_cat_num) |
|
894 apply (simp add: word_of_int_power_hom [symmetric] new_word_of_int_hom_syms) |
|
895 done |
|
896 |
|
897 lemma of_bl_False [simp]: |
|
898 "of_bl (False#xs) = of_bl xs" |
|
899 by (rule word_eqI) |
|
900 (auto simp add: test_bit_of_bl nth_append) |
|
901 |
|
902 lemma of_bl_True: |
|
903 "(of_bl (True#xs)::'a::len word) = 2^length xs + of_bl xs" |
|
904 by (subst of_bl_append [where xs="[True]", simplified]) |
|
905 (simp add: word_1_bl) |
|
906 |
|
907 lemma of_bl_Cons: |
|
908 "of_bl (x#xs) = of_bool x * 2^length xs + of_bl xs" |
|
909 by (cases x) (simp_all add: of_bl_True) |
|
910 |
|
911 lemma split_uint_lem: "bin_split n (uint (w :: 'a :: len0 word)) = (a, b) ==> |
|
912 a = bintrunc (len_of TYPE('a) - n) a & b = bintrunc (len_of TYPE('a)) b" |
|
913 apply (frule word_ubin.norm_Rep [THEN ssubst]) |
|
914 apply (drule bin_split_trunc1) |
|
915 apply (drule sym [THEN trans]) |
|
916 apply assumption |
|
917 apply safe |
|
918 done |
|
919 |
|
920 lemma word_split_bl': |
|
921 "std = size c - size b ==> (word_split c = (a, b)) ==> |
|
922 (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c)))" |
|
923 apply (unfold word_split_bin') |
|
924 apply safe |
|
925 defer |
|
926 apply (clarsimp split: prod.splits) |
|
927 apply (drule word_ubin.norm_Rep [THEN ssubst]) |
|
928 apply (drule split_bintrunc) |
|
929 apply (simp add : of_bl_def bl2bin_drop word_size |
|
930 word_ubin.norm_eq_iff [symmetric] min_def del : word_ubin.norm_Rep) |
|
931 apply (clarsimp split: prod.splits) |
|
932 apply (frule split_uint_lem [THEN conjunct1]) |
|
933 apply (unfold word_size) |
|
934 apply (cases "len_of TYPE('a) >= len_of TYPE('b)") |
|
935 defer |
|
936 apply (simp add: word_0_bl word_0_wi_Pls) |
|
937 apply (simp add : of_bl_def to_bl_def) |
|
938 apply (subst bin_split_take1 [symmetric]) |
|
939 prefer 2 |
|
940 apply assumption |
|
941 apply simp |
|
942 apply (erule thin_rl) |
|
943 apply (erule arg_cong [THEN trans]) |
|
944 apply (simp add : word_ubin.norm_eq_iff [symmetric]) |
|
945 done |
|
946 |
|
947 lemma word_split_bl: "std = size c - size b ==> |
|
948 (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c))) <-> |
|
949 word_split c = (a, b)" |
|
950 apply (rule iffI) |
|
951 defer |
|
952 apply (erule (1) word_split_bl') |
|
953 apply (case_tac "word_split c") |
|
954 apply (auto simp add : word_size) |
|
955 apply (frule word_split_bl' [rotated]) |
|
956 apply (auto simp add : word_size) |
|
957 done |
|
958 |
|
959 lemma word_split_bl_eq: |
|
960 "(word_split (c::'a::len word) :: ('c :: len0 word * 'd :: len0 word)) = |
|
961 (of_bl (take (len_of TYPE('a::len) - len_of TYPE('d::len0)) (to_bl c)), |
|
962 of_bl (drop (len_of TYPE('a) - len_of TYPE('d)) (to_bl c)))" |
|
963 apply (rule word_split_bl [THEN iffD1]) |
|
964 apply (unfold word_size) |
|
965 apply (rule refl conjI)+ |
|
966 done |
|
967 |
|
968 -- "keep quantifiers for use in simplification" |
|
969 lemma test_bit_split': |
|
970 "word_split c = (a, b) --> (ALL n m. b !! n = (n < size b & c !! n) & |
|
971 a !! m = (m < size a & c !! (m + size b)))" |
|
972 apply (unfold word_split_bin' test_bit_bin) |
|
973 apply (clarify) |
|
974 apply (clarsimp simp: word_ubin.eq_norm nth_bintr word_size split: prod.splits) |
|
975 apply (drule bin_nth_split) |
|
976 apply safe |
|
977 apply (simp_all add: add_commute) |
|
978 apply (erule bin_nth_uint_imp)+ |
|
979 done |
|
980 |
|
981 lemmas test_bit_split = |
|
982 test_bit_split' [THEN mp, simplified all_simps, standard] |
|
983 |
|
984 lemma test_bit_split_eq: "word_split c = (a, b) <-> |
|
985 ((ALL n::nat. b !! n = (n < size b & c !! n)) & |
|
986 (ALL m::nat. a !! m = (m < size a & c !! (m + size b))))" |
|
987 apply (rule_tac iffI) |
|
988 apply (rule_tac conjI) |
|
989 apply (erule test_bit_split [THEN conjunct1]) |
|
990 apply (erule test_bit_split [THEN conjunct2]) |
|
991 apply (case_tac "word_split c") |
|
992 apply (frule test_bit_split) |
|
993 apply (erule trans) |
|
994 apply (fastsimp intro ! : word_eqI simp add : word_size) |
|
995 done |
|
996 |
|
997 -- {* this odd result is analogous to ucast\_id, |
|
998 result to the length given by the result type *} |
|
999 |
|
1000 lemma word_cat_id: "word_cat a b = b" |
|
1001 unfolding word_cat_bin' by (simp add: word_ubin.inverse_norm) |
|
1002 |
|
1003 -- "limited hom result" |
|
1004 lemma word_cat_hom: |
|
1005 "len_of TYPE('a::len0) <= len_of TYPE('b::len0) + len_of TYPE ('c::len0) |
|
1006 ==> |
|
1007 (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) = |
|
1008 word_of_int (bin_cat w (size b) (uint b))" |
|
1009 apply (unfold word_cat_def word_size) |
|
1010 apply (clarsimp simp add : word_ubin.norm_eq_iff [symmetric] |
|
1011 word_ubin.eq_norm bintr_cat min_def) |
|
1012 apply arith |
|
1013 done |
|
1014 |
|
1015 lemma word_cat_split_alt: |
|
1016 "size w <= size u + size v ==> word_split w = (u, v) ==> word_cat u v = w" |
|
1017 apply (rule word_eqI) |
|
1018 apply (drule test_bit_split) |
|
1019 apply (clarsimp simp add : test_bit_cat word_size) |
|
1020 apply safe |
|
1021 apply arith |
|
1022 done |
|
1023 |
|
1024 lemmas word_cat_split_size = |
|
1025 sym [THEN [2] word_cat_split_alt [symmetric], standard] |
|
1026 |
|
1027 |
|
1028 subsection "Split and slice" |
|
1029 |
|
1030 lemma split_slices: |
|
1031 "word_split w = (u, v) ==> u = slice (size v) w & v = slice 0 w" |
|
1032 apply (drule test_bit_split) |
|
1033 apply (rule conjI) |
|
1034 apply (rule word_eqI, clarsimp simp: nth_slice word_size)+ |
|
1035 done |
|
1036 |
|
1037 lemma slice_cat1': |
|
1038 "wc = word_cat a b ==> size wc >= size a + size b ==> slice (size b) wc = a" |
|
1039 apply safe |
|
1040 apply (rule word_eqI) |
|
1041 apply (simp add: nth_slice test_bit_cat word_size) |
|
1042 done |
|
1043 |
|
1044 lemmas slice_cat1 = refl [THEN slice_cat1'] |
|
1045 lemmas slice_cat2 = trans [OF slice_id word_cat_id] |
|
1046 |
|
1047 lemma cat_slices: |
|
1048 "a = slice n c ==> b = slice 0 c ==> n = size b ==> \ |
|
1049 size a + size b >= size c ==> word_cat a b = c" |
|
1050 apply safe |
|
1051 apply (rule word_eqI) |
|
1052 apply (simp add: nth_slice test_bit_cat word_size) |
|
1053 apply safe |
|
1054 apply arith |
|
1055 done |
|
1056 |
|
1057 lemma word_split_cat_alt: |
|
1058 "w = word_cat u v ==> size u + size v <= size w ==> word_split w = (u, v)" |
|
1059 apply (case_tac "word_split ?w") |
|
1060 apply (rule trans, assumption) |
|
1061 apply (drule test_bit_split) |
|
1062 apply safe |
|
1063 apply (rule word_eqI, clarsimp simp: test_bit_cat word_size)+ |
|
1064 done |
|
1065 |
|
1066 lemmas word_cat_bl_no_bin [simp] = |
|
1067 word_cat_bl [where a="number_of ?a" |
|
1068 and b="number_of ?b", |
|
1069 unfolded to_bl_no_bin] |
|
1070 |
|
1071 lemmas word_split_bl_no_bin [simp] = |
|
1072 word_split_bl_eq [where c="number_of ?c", unfolded to_bl_no_bin] |
|
1073 |
|
1074 -- {* this odd result arises from the fact that the statement of the |
|
1075 result implies that the decoded words are of the same type, |
|
1076 and therefore of the same length, as the original word *} |
|
1077 |
|
1078 lemma word_rsplit_same: "word_rsplit w = [w]" |
|
1079 unfolding word_rsplit_def by (simp add : bin_rsplit_all) |
|
1080 |
|
1081 lemma word_rsplit_empty_iff_size: |
|
1082 "(word_rsplit w = []) = (size w = 0)" |
|
1083 unfolding word_rsplit_def bin_rsplit_def word_size |
|
1084 by (simp add: bin_rsplit_aux_simp_alt Let_def split: split_split) |
|
1085 |
|
1086 lemma test_bit_rsplit: |
|
1087 "sw = word_rsplit w ==> m < size (hd sw :: 'a :: len word) ==> |
|
1088 k < length sw ==> (rev sw ! k) !! m = (w !! (k * size (hd sw) + m))" |
|
1089 apply (unfold word_rsplit_def word_test_bit_def) |
|
1090 apply (rule trans) |
|
1091 apply (rule_tac f = "%x. bin_nth x m" in arg_cong) |
|
1092 apply (rule nth_map [symmetric]) |
|
1093 apply simp |
|
1094 apply (rule bin_nth_rsplit) |
|
1095 apply simp_all |
|
1096 apply (simp add : word_size rev_map map_compose [symmetric]) |
|
1097 apply (rule trans) |
|
1098 defer |
|
1099 apply (rule map_ident [THEN fun_cong]) |
|
1100 apply (rule refl [THEN map_cong]) |
|
1101 apply (simp add : word_ubin.eq_norm) |
|
1102 apply (erule bin_rsplit_size_sign [OF len_gt_0 refl]) |
|
1103 done |
|
1104 |
|
1105 lemma word_rcat_bl: "word_rcat wl == of_bl (concat (map to_bl wl))" |
|
1106 unfolding word_rcat_def to_bl_def' of_bl_def |
|
1107 by (clarsimp simp add : bin_rcat_bl map_compose) |
|
1108 |
|
1109 lemma size_rcat_lem': |
|
1110 "size (concat (map to_bl wl)) = length wl * size (hd wl)" |
|
1111 unfolding word_size by (induct wl) auto |
|
1112 |
|
1113 lemmas size_rcat_lem = size_rcat_lem' [unfolded word_size] |
|
1114 |
|
1115 lemmas td_gal_lt_len = len_gt_0 [THEN td_gal_lt, standard] |
|
1116 |
|
1117 lemma nth_rcat_lem' [rule_format] : |
|
1118 "sw = size (hd wl :: 'a :: len word) ==> (ALL n. n < size wl * sw --> |
|
1119 rev (concat (map to_bl wl)) ! n = |
|
1120 rev (to_bl (rev wl ! (n div sw))) ! (n mod sw))" |
|
1121 apply (unfold word_size) |
|
1122 apply (induct "wl") |
|
1123 apply clarsimp |
|
1124 apply (clarsimp simp add : nth_append size_rcat_lem) |
|
1125 apply (simp (no_asm_use) only: mult_Suc [symmetric] |
|
1126 td_gal_lt_len less_Suc_eq_le mod_div_equality') |
|
1127 apply clarsimp |
|
1128 done |
|
1129 |
|
1130 lemmas nth_rcat_lem = refl [THEN nth_rcat_lem', unfolded word_size] |
|
1131 |
|
1132 lemma test_bit_rcat: |
|
1133 "sw = size (hd wl :: 'a :: len word) ==> rc = word_rcat wl ==> rc !! n = |
|
1134 (n < size rc & n div sw < size wl & (rev wl) ! (n div sw) !! (n mod sw))" |
|
1135 apply (unfold word_rcat_bl word_size) |
|
1136 apply (clarsimp simp add : |
|
1137 test_bit_of_bl size_rcat_lem word_size td_gal_lt_len) |
|
1138 apply safe |
|
1139 apply (auto simp add : |
|
1140 test_bit_bl word_size td_gal_lt_len [THEN iffD2, THEN nth_rcat_lem]) |
|
1141 done |
|
1142 |
|
1143 lemma foldl_eq_foldr [rule_format] : |
|
1144 "ALL x. foldl op + x xs = foldr op + (x # xs) (0 :: 'a :: comm_monoid_add)" |
|
1145 by (induct xs) (auto simp add : add_assoc) |
|
1146 |
|
1147 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong] |
|
1148 |
|
1149 lemmas test_bit_rsplit_alt = |
|
1150 trans [OF nth_rev_alt [THEN test_bit_cong] |
|
1151 test_bit_rsplit [OF refl asm_rl diff_Suc_less]] |
|
1152 |
|
1153 -- "lazy way of expressing that u and v, and su and sv, have same types" |
|
1154 lemma word_rsplit_len_indep': |
|
1155 "[u,v] = p ==> [su,sv] = q ==> word_rsplit u = su ==> |
|
1156 word_rsplit v = sv ==> length su = length sv" |
|
1157 apply (unfold word_rsplit_def) |
|
1158 apply (auto simp add : bin_rsplit_len_indep) |
|
1159 done |
|
1160 |
|
1161 lemmas word_rsplit_len_indep = word_rsplit_len_indep' [OF refl refl refl refl] |
|
1162 |
|
1163 lemma length_word_rsplit_size: |
|
1164 "n = len_of TYPE ('a :: len) ==> |
|
1165 (length (word_rsplit w :: 'a word list) <= m) = (size w <= m * n)" |
|
1166 apply (unfold word_rsplit_def word_size) |
|
1167 apply (clarsimp simp add : bin_rsplit_len_le) |
|
1168 done |
|
1169 |
|
1170 lemmas length_word_rsplit_lt_size = |
|
1171 length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]] |
|
1172 |
|
1173 lemma length_word_rsplit_exp_size: |
|
1174 "n = len_of TYPE ('a :: len) ==> |
|
1175 length (word_rsplit w :: 'a word list) = (size w + n - 1) div n" |
|
1176 unfolding word_rsplit_def by (clarsimp simp add : word_size bin_rsplit_len) |
|
1177 |
|
1178 lemma length_word_rsplit_even_size: |
|
1179 "n = len_of TYPE ('a :: len) ==> size w = m * n ==> |
|
1180 length (word_rsplit w :: 'a word list) = m" |
|
1181 by (clarsimp simp add : length_word_rsplit_exp_size given_quot_alt) |
|
1182 |
|
1183 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size] |
|
1184 |
|
1185 (* alternative proof of word_rcat_rsplit *) |
|
1186 lemmas tdle = iffD2 [OF split_div_lemma refl, THEN conjunct1] |
|
1187 lemmas dtle = xtr4 [OF tdle mult_commute] |
|
1188 |
|
1189 lemma word_rcat_rsplit: "word_rcat (word_rsplit w) = w" |
|
1190 apply (rule word_eqI) |
|
1191 apply (clarsimp simp add : test_bit_rcat word_size) |
|
1192 apply (subst refl [THEN test_bit_rsplit]) |
|
1193 apply (simp_all add: word_size |
|
1194 refl [THEN length_word_rsplit_size [simplified le_def, simplified]]) |
|
1195 apply safe |
|
1196 apply (erule xtr7, rule len_gt_0 [THEN dtle])+ |
|
1197 done |
|
1198 |
|
1199 lemma size_word_rsplit_rcat_size': |
|
1200 "word_rcat (ws :: 'a :: len word list) = frcw ==> |
|
1201 size frcw = length ws * len_of TYPE ('a) ==> |
|
1202 size (hd [word_rsplit frcw, ws]) = size ws" |
|
1203 apply (clarsimp simp add : word_size length_word_rsplit_exp_size') |
|
1204 apply (fast intro: given_quot_alt) |
|
1205 done |
|
1206 |
|
1207 lemmas size_word_rsplit_rcat_size = |
|
1208 size_word_rsplit_rcat_size' [simplified] |
|
1209 |
|
1210 lemma msrevs: |
|
1211 fixes n::nat |
|
1212 shows "0 < n \<Longrightarrow> (k * n + m) div n = m div n + k" |
|
1213 and "(k * n + m) mod n = m mod n" |
|
1214 by (auto simp: add_commute) |
|
1215 |
|
1216 lemma word_rsplit_rcat_size': |
|
1217 "word_rcat (ws :: 'a :: len word list) = frcw ==> |
|
1218 size frcw = length ws * len_of TYPE ('a) ==> word_rsplit frcw = ws" |
|
1219 apply (frule size_word_rsplit_rcat_size, assumption) |
|
1220 apply (clarsimp simp add : word_size) |
|
1221 apply (rule nth_equalityI, assumption) |
|
1222 apply clarsimp |
|
1223 apply (rule word_eqI) |
|
1224 apply (rule trans) |
|
1225 apply (rule test_bit_rsplit_alt) |
|
1226 apply (clarsimp simp: word_size)+ |
|
1227 apply (rule trans) |
|
1228 apply (rule test_bit_rcat [OF refl refl]) |
|
1229 apply (simp add : word_size msrevs) |
|
1230 apply (subst nth_rev) |
|
1231 apply arith |
|
1232 apply (simp add : le0 [THEN [2] xtr7, THEN diff_Suc_less]) |
|
1233 apply safe |
|
1234 apply (simp add : diff_mult_distrib) |
|
1235 apply (rule mpl_lem) |
|
1236 apply (cases "size ws") |
|
1237 apply simp_all |
|
1238 done |
|
1239 |
|
1240 lemmas word_rsplit_rcat_size = refl [THEN word_rsplit_rcat_size'] |
|
1241 |
|
1242 |
|
1243 section "Rotation" |
|
1244 |
|
1245 lemmas rotater_0' [simp] = rotater_def [where n = "0", simplified] |
|
1246 |
|
1247 lemmas word_rot_defs = word_roti_def word_rotr_def word_rotl_def |
|
1248 |
|
1249 lemma rotate_eq_mod: |
|
1250 "m mod length xs = n mod length xs ==> rotate m xs = rotate n xs" |
|
1251 apply (rule box_equals) |
|
1252 defer |
|
1253 apply (rule rotate_conv_mod [symmetric])+ |
|
1254 apply simp |
|
1255 done |
|
1256 |
|
1257 lemmas rotate_eqs [standard] = |
|
1258 trans [OF rotate0 [THEN fun_cong] id_apply] |
|
1259 rotate_rotate [symmetric] |
|
1260 rotate_id |
|
1261 rotate_conv_mod |
|
1262 rotate_eq_mod |
|
1263 |
|
1264 |
|
1265 subsection "Rotation of list to right" |
|
1266 |
|
1267 lemma rotate1_rl': "rotater1 (l @ [a]) = a # l" |
|
1268 unfolding rotater1_def by (cases l) auto |
|
1269 |
|
1270 lemma rotate1_rl [simp] : "rotater1 (rotate1 l) = l" |
|
1271 apply (unfold rotater1_def) |
|
1272 apply (cases "l") |
|
1273 apply (case_tac [2] "list") |
|
1274 apply auto |
|
1275 done |
|
1276 |
|
1277 lemma rotate1_lr [simp] : "rotate1 (rotater1 l) = l" |
|
1278 unfolding rotater1_def by (cases l) auto |
|
1279 |
|
1280 lemma rotater1_rev': "rotater1 (rev xs) = rev (rotate1 xs)" |
|
1281 apply (cases "xs") |
|
1282 apply (simp add : rotater1_def) |
|
1283 apply (simp add : rotate1_rl') |
|
1284 done |
|
1285 |
|
1286 lemma rotater_rev': "rotater n (rev xs) = rev (rotate n xs)" |
|
1287 unfolding rotater_def by (induct n) (auto intro: rotater1_rev') |
|
1288 |
|
1289 lemmas rotater_rev = rotater_rev' [where xs = "rev ?ys", simplified] |
|
1290 |
|
1291 lemma rotater_drop_take: |
|
1292 "rotater n xs = |
|
1293 drop (length xs - n mod length xs) xs @ |
|
1294 take (length xs - n mod length xs) xs" |
|
1295 by (clarsimp simp add : rotater_rev rotate_drop_take rev_take rev_drop) |
|
1296 |
|
1297 lemma rotater_Suc [simp] : |
|
1298 "rotater (Suc n) xs = rotater1 (rotater n xs)" |
|
1299 unfolding rotater_def by auto |
|
1300 |
|
1301 lemma rotate_inv_plus [rule_format] : |
|
1302 "ALL k. k = m + n --> rotater k (rotate n xs) = rotater m xs & |
|
1303 rotate k (rotater n xs) = rotate m xs & |
|
1304 rotater n (rotate k xs) = rotate m xs & |
|
1305 rotate n (rotater k xs) = rotater m xs" |
|
1306 unfolding rotater_def rotate_def |
|
1307 by (induct n) (auto intro: funpow_swap1 [THEN trans]) |
|
1308 |
|
1309 lemmas rotate_inv_rel = le_add_diff_inverse2 [symmetric, THEN rotate_inv_plus] |
|
1310 |
|
1311 lemmas rotate_inv_eq = order_refl [THEN rotate_inv_rel, simplified] |
|
1312 |
|
1313 lemmas rotate_lr [simp] = rotate_inv_eq [THEN conjunct1, standard] |
|
1314 lemmas rotate_rl [simp] = |
|
1315 rotate_inv_eq [THEN conjunct2, THEN conjunct1, standard] |
|
1316 |
|
1317 lemma rotate_gal: "(rotater n xs = ys) = (rotate n ys = xs)" |
|
1318 by auto |
|
1319 |
|
1320 lemma rotate_gal': "(ys = rotater n xs) = (xs = rotate n ys)" |
|
1321 by auto |
|
1322 |
|
1323 lemma length_rotater [simp]: |
|
1324 "length (rotater n xs) = length xs" |
|
1325 by (simp add : rotater_rev) |
|
1326 |
|
1327 lemmas rrs0 = rotate_eqs [THEN restrict_to_left, |
|
1328 simplified rotate_gal [symmetric] rotate_gal' [symmetric], standard] |
|
1329 lemmas rrs1 = rrs0 [THEN refl [THEN rev_iffD1]] |
|
1330 lemmas rotater_eqs = rrs1 [simplified length_rotater, standard] |
|
1331 lemmas rotater_0 = rotater_eqs (1) |
|
1332 lemmas rotater_add = rotater_eqs (2) |
|
1333 |
|
1334 |
|
1335 subsection "map, app2, commuting with rotate(r)" |
|
1336 |
|
1337 lemma last_map: "xs ~= [] ==> last (map f xs) = f (last xs)" |
|
1338 by (induct xs) auto |
|
1339 |
|
1340 lemma butlast_map: |
|
1341 "xs ~= [] ==> butlast (map f xs) = map f (butlast xs)" |
|
1342 by (induct xs) auto |
|
1343 |
|
1344 lemma rotater1_map: "rotater1 (map f xs) = map f (rotater1 xs)" |
|
1345 unfolding rotater1_def |
|
1346 by (cases xs) (auto simp add: last_map butlast_map) |
|
1347 |
|
1348 lemma rotater_map: |
|
1349 "rotater n (map f xs) = map f (rotater n xs)" |
|
1350 unfolding rotater_def |
|
1351 by (induct n) (auto simp add : rotater1_map) |
|
1352 |
|
1353 lemma but_last_zip [rule_format] : |
|
1354 "ALL ys. length xs = length ys --> xs ~= [] --> |
|
1355 last (zip xs ys) = (last xs, last ys) & |
|
1356 butlast (zip xs ys) = zip (butlast xs) (butlast ys)" |
|
1357 apply (induct "xs") |
|
1358 apply auto |
|
1359 apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+ |
|
1360 done |
|
1361 |
|
1362 lemma but_last_app2 [rule_format] : |
|
1363 "ALL ys. length xs = length ys --> xs ~= [] --> |
|
1364 last (app2 f xs ys) = f (last xs) (last ys) & |
|
1365 butlast (app2 f xs ys) = app2 f (butlast xs) (butlast ys)" |
|
1366 apply (induct "xs") |
|
1367 apply auto |
|
1368 apply (unfold app2_def) |
|
1369 apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+ |
|
1370 done |
|
1371 |
|
1372 lemma rotater1_zip: |
|
1373 "length xs = length ys ==> |
|
1374 rotater1 (zip xs ys) = zip (rotater1 xs) (rotater1 ys)" |
|
1375 apply (unfold rotater1_def) |
|
1376 apply (cases "xs") |
|
1377 apply auto |
|
1378 apply ((case_tac ys, auto simp: neq_Nil_conv but_last_zip)[1])+ |
|
1379 done |
|
1380 |
|
1381 lemma rotater1_app2: |
|
1382 "length xs = length ys ==> |
|
1383 rotater1 (app2 f xs ys) = app2 f (rotater1 xs) (rotater1 ys)" |
|
1384 unfolding app2_def by (simp add: rotater1_map rotater1_zip) |
|
1385 |
|
1386 lemmas lrth = |
|
1387 box_equals [OF asm_rl length_rotater [symmetric] |
|
1388 length_rotater [symmetric], |
|
1389 THEN rotater1_app2] |
|
1390 |
|
1391 lemma rotater_app2: |
|
1392 "length xs = length ys ==> |
|
1393 rotater n (app2 f xs ys) = app2 f (rotater n xs) (rotater n ys)" |
|
1394 by (induct n) (auto intro!: lrth) |
|
1395 |
|
1396 lemma rotate1_app2: |
|
1397 "length xs = length ys ==> |
|
1398 rotate1 (app2 f xs ys) = app2 f (rotate1 xs) (rotate1 ys)" |
|
1399 apply (unfold app2_def) |
|
1400 apply (cases xs) |
|
1401 apply (cases ys, auto simp add : rotate1_def)+ |
|
1402 done |
|
1403 |
|
1404 lemmas lth = box_equals [OF asm_rl length_rotate [symmetric] |
|
1405 length_rotate [symmetric], THEN rotate1_app2] |
|
1406 |
|
1407 lemma rotate_app2: |
|
1408 "length xs = length ys ==> |
|
1409 rotate n (app2 f xs ys) = app2 f (rotate n xs) (rotate n ys)" |
|
1410 by (induct n) (auto intro!: lth) |
|
1411 |
|
1412 |
|
1413 -- "corresponding equalities for word rotation" |
|
1414 |
|
1415 lemma to_bl_rotl: |
|
1416 "to_bl (word_rotl n w) = rotate n (to_bl w)" |
|
1417 by (simp add: word_bl.Abs_inverse' word_rotl_def) |
|
1418 |
|
1419 lemmas blrs0 = rotate_eqs [THEN to_bl_rotl [THEN trans]] |
|
1420 |
|
1421 lemmas word_rotl_eqs = |
|
1422 blrs0 [simplified word_bl.Rep' word_bl.Rep_inject to_bl_rotl [symmetric]] |
|
1423 |
|
1424 lemma to_bl_rotr: |
|
1425 "to_bl (word_rotr n w) = rotater n (to_bl w)" |
|
1426 by (simp add: word_bl.Abs_inverse' word_rotr_def) |
|
1427 |
|
1428 lemmas brrs0 = rotater_eqs [THEN to_bl_rotr [THEN trans]] |
|
1429 |
|
1430 lemmas word_rotr_eqs = |
|
1431 brrs0 [simplified word_bl.Rep' word_bl.Rep_inject to_bl_rotr [symmetric]] |
|
1432 |
|
1433 declare word_rotr_eqs (1) [simp] |
|
1434 declare word_rotl_eqs (1) [simp] |
|
1435 |
|
1436 lemma |
|
1437 word_rot_rl [simp]: |
|
1438 "word_rotl k (word_rotr k v) = v" and |
|
1439 word_rot_lr [simp]: |
|
1440 "word_rotr k (word_rotl k v) = v" |
|
1441 by (auto simp add: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric]) |
|
1442 |
|
1443 lemma |
|
1444 word_rot_gal: |
|
1445 "(word_rotr n v = w) = (word_rotl n w = v)" and |
|
1446 word_rot_gal': |
|
1447 "(w = word_rotr n v) = (v = word_rotl n w)" |
|
1448 by (auto simp: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric] |
|
1449 dest: sym) |
|
1450 |
|
1451 lemma word_rotr_rev: |
|
1452 "word_rotr n w = word_reverse (word_rotl n (word_reverse w))" |
|
1453 by (simp add: word_bl.Rep_inject [symmetric] to_bl_word_rev |
|
1454 to_bl_rotr to_bl_rotl rotater_rev) |
|
1455 |
|
1456 lemma word_roti_0 [simp]: "word_roti 0 w = w" |
|
1457 by (unfold word_rot_defs) auto |
|
1458 |
|
1459 lemmas abl_cong = arg_cong [where f = "of_bl"] |
|
1460 |
|
1461 lemma word_roti_add: |
|
1462 "word_roti (m + n) w = word_roti m (word_roti n w)" |
|
1463 proof - |
|
1464 have rotater_eq_lem: |
|
1465 "\<And>m n xs. m = n ==> rotater m xs = rotater n xs" |
|
1466 by auto |
|
1467 |
|
1468 have rotate_eq_lem: |
|
1469 "\<And>m n xs. m = n ==> rotate m xs = rotate n xs" |
|
1470 by auto |
|
1471 |
|
1472 note rpts [symmetric, standard] = |
|
1473 rotate_inv_plus [THEN conjunct1] |
|
1474 rotate_inv_plus [THEN conjunct2, THEN conjunct1] |
|
1475 rotate_inv_plus [THEN conjunct2, THEN conjunct2, THEN conjunct1] |
|
1476 rotate_inv_plus [THEN conjunct2, THEN conjunct2, THEN conjunct2] |
|
1477 |
|
1478 note rrp = trans [symmetric, OF rotate_rotate rotate_eq_lem] |
|
1479 note rrrp = trans [symmetric, OF rotater_add [symmetric] rotater_eq_lem] |
|
1480 |
|
1481 show ?thesis |
|
1482 apply (unfold word_rot_defs) |
|
1483 apply (simp only: split: split_if) |
|
1484 apply (safe intro!: abl_cong) |
|
1485 apply (simp_all only: to_bl_rotl [THEN word_bl.Rep_inverse'] |
|
1486 to_bl_rotl |
|
1487 to_bl_rotr [THEN word_bl.Rep_inverse'] |
|
1488 to_bl_rotr) |
|
1489 apply (rule rrp rrrp rpts, |
|
1490 simp add: nat_add_distrib [symmetric] |
|
1491 nat_diff_distrib [symmetric])+ |
|
1492 done |
|
1493 qed |
|
1494 |
|
1495 lemma word_roti_conv_mod': "word_roti n w = word_roti (n mod int (size w)) w" |
|
1496 apply (unfold word_rot_defs) |
|
1497 apply (cut_tac y="size w" in gt_or_eq_0) |
|
1498 apply (erule disjE) |
|
1499 apply simp_all |
|
1500 apply (safe intro!: abl_cong) |
|
1501 apply (rule rotater_eqs) |
|
1502 apply (simp add: word_size nat_mod_distrib) |
|
1503 apply (simp add: rotater_add [symmetric] rotate_gal [symmetric]) |
|
1504 apply (rule rotater_eqs) |
|
1505 apply (simp add: word_size nat_mod_distrib) |
|
1506 apply (rule int_eq_0_conv [THEN iffD1]) |
|
1507 apply (simp only: zmod_int zadd_int [symmetric]) |
|
1508 apply (simp add: rdmods) |
|
1509 done |
|
1510 |
|
1511 lemmas word_roti_conv_mod = word_roti_conv_mod' [unfolded word_size] |
|
1512 |
|
1513 |
|
1514 subsection "Word rotation commutes with bit-wise operations" |
|
1515 |
|
1516 (* using locale to not pollute lemma namespace *) |
|
1517 locale word_rotate |
|
1518 |
|
1519 context word_rotate |
|
1520 begin |
|
1521 |
|
1522 lemmas word_rot_defs' = to_bl_rotl to_bl_rotr |
|
1523 |
|
1524 lemmas blwl_syms [symmetric] = bl_word_not bl_word_and bl_word_or bl_word_xor |
|
1525 |
|
1526 lemmas lbl_lbl = trans [OF word_bl.Rep' word_bl.Rep' [symmetric]] |
|
1527 |
|
1528 lemmas ths_app2 [OF lbl_lbl] = rotate_app2 rotater_app2 |
|
1529 |
|
1530 lemmas ths_map [where xs = "to_bl v"] = rotate_map rotater_map |
|
1531 |
|
1532 lemmas th1s [simplified word_rot_defs' [symmetric]] = ths_app2 ths_map |
|
1533 |
|
1534 lemma word_rot_logs: |
|
1535 "word_rotl n (NOT v) = NOT word_rotl n v" |
|
1536 "word_rotr n (NOT v) = NOT word_rotr n v" |
|
1537 "word_rotl n (x AND y) = word_rotl n x AND word_rotl n y" |
|
1538 "word_rotr n (x AND y) = word_rotr n x AND word_rotr n y" |
|
1539 "word_rotl n (x OR y) = word_rotl n x OR word_rotl n y" |
|
1540 "word_rotr n (x OR y) = word_rotr n x OR word_rotr n y" |
|
1541 "word_rotl n (x XOR y) = word_rotl n x XOR word_rotl n y" |
|
1542 "word_rotr n (x XOR y) = word_rotr n x XOR word_rotr n y" |
|
1543 by (rule word_bl.Rep_eqD, |
|
1544 rule word_rot_defs' [THEN trans], |
|
1545 simp only: blwl_syms [symmetric], |
|
1546 rule th1s [THEN trans], |
|
1547 rule refl)+ |
|
1548 end |
|
1549 |
|
1550 lemmas word_rot_logs = word_rotate.word_rot_logs |
|
1551 |
|
1552 lemmas bl_word_rotl_dt = trans [OF to_bl_rotl rotate_drop_take, |
|
1553 simplified word_bl.Rep', standard] |
|
1554 |
|
1555 lemmas bl_word_rotr_dt = trans [OF to_bl_rotr rotater_drop_take, |
|
1556 simplified word_bl.Rep', standard] |
|
1557 |
|
1558 lemma bl_word_roti_dt': |
|
1559 "n = nat ((- i) mod int (size (w :: 'a :: len word))) ==> |
|
1560 to_bl (word_roti i w) = drop n (to_bl w) @ take n (to_bl w)" |
|
1561 apply (unfold word_roti_def) |
|
1562 apply (simp add: bl_word_rotl_dt bl_word_rotr_dt word_size) |
|
1563 apply safe |
|
1564 apply (simp add: zmod_zminus1_eq_if) |
|
1565 apply safe |
|
1566 apply (simp add: nat_mult_distrib) |
|
1567 apply (simp add: nat_diff_distrib [OF pos_mod_sign pos_mod_conj |
|
1568 [THEN conjunct2, THEN order_less_imp_le]] |
|
1569 nat_mod_distrib) |
|
1570 apply (simp add: nat_mod_distrib) |
|
1571 done |
|
1572 |
|
1573 lemmas bl_word_roti_dt = bl_word_roti_dt' [unfolded word_size] |
|
1574 |
|
1575 lemmas word_rotl_dt = bl_word_rotl_dt |
|
1576 [THEN word_bl.Rep_inverse' [symmetric], standard] |
|
1577 lemmas word_rotr_dt = bl_word_rotr_dt |
|
1578 [THEN word_bl.Rep_inverse' [symmetric], standard] |
|
1579 lemmas word_roti_dt = bl_word_roti_dt |
|
1580 [THEN word_bl.Rep_inverse' [symmetric], standard] |
|
1581 |
|
1582 lemma word_rotx_0 [simp] : "word_rotr i 0 = 0 & word_rotl i 0 = 0" |
|
1583 by (simp add : word_rotr_dt word_rotl_dt to_bl_0 replicate_add [symmetric]) |
|
1584 |
|
1585 lemma word_roti_0' [simp] : "word_roti n 0 = 0" |
|
1586 unfolding word_roti_def by auto |
|
1587 |
|
1588 lemmas word_rotr_dt_no_bin' [simp] = |
|
1589 word_rotr_dt [where w="number_of ?w", unfolded to_bl_no_bin] |
|
1590 |
|
1591 lemmas word_rotl_dt_no_bin' [simp] = |
|
1592 word_rotl_dt [where w="number_of ?w", unfolded to_bl_no_bin] |
|
1593 |
|
1594 declare word_roti_def [simp] |
|
1595 |
|
1596 end |
|
1597 |