93 apply (unfold scast_def sint_n1) |
93 apply (unfold scast_def sint_n1) |
94 apply (unfold word_number_of_alt) |
94 apply (unfold word_number_of_alt) |
95 apply (rule refl) |
95 apply (rule refl) |
96 done |
96 done |
97 |
97 |
98 lemma uint_1 [simp] : "uint (1 :: 'a :: len word) = 1" |
98 lemma uint_1 [simp] : "uint (1 :: 'a :: finite word) = 1" |
99 unfolding word_1_wi |
99 unfolding word_1_wi |
100 by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps) |
100 by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps) |
101 |
101 |
102 lemma unat_1 [simp] : "unat (1 :: 'a :: len word) = 1" |
102 lemma unat_1 [simp] : "unat (1 :: 'a :: finite word) = 1" |
103 by (unfold unat_def uint_1) auto |
103 by (unfold unat_def uint_1) auto |
104 |
104 |
105 lemma ucast_1 [simp] : "ucast (1 :: 'a :: len word) = 1" |
105 lemma ucast_1 [simp] : "ucast (1 :: 'a :: finite word) = 1" |
106 unfolding ucast_def word_1_wi |
106 unfolding ucast_def word_1_wi |
107 by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps) |
107 by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps) |
108 |
108 |
109 (* abstraction preserves the operations |
109 (* abstraction preserves the operations |
110 (the definitions tell this for bins in range uint) *) |
110 (the definitions tell this for bins in range uint) *) |
250 lemmas word_mult_ac = word_mult_commute word_mult_assoc word_mult_left_commute |
250 lemmas word_mult_ac = word_mult_commute word_mult_assoc word_mult_left_commute |
251 |
251 |
252 lemmas word_plus_ac0 = word_add_0 word_add_0_right word_add_ac |
252 lemmas word_plus_ac0 = word_add_0 word_add_0_right word_add_ac |
253 lemmas word_times_ac1 = word_mult_1 word_mult_1_right word_mult_ac |
253 lemmas word_times_ac1 = word_mult_1 word_mult_1_right word_mult_ac |
254 |
254 |
255 instance word :: (len0) semigroup_add |
255 instance word :: (type) semigroup_add |
256 by intro_classes (simp add: word_add_assoc) |
256 by intro_classes (simp add: word_add_assoc) |
257 |
257 |
258 instance word :: (len0) ring |
258 instance word :: (type) ring |
259 by intro_classes |
259 by intro_classes |
260 (auto simp: word_arith_eqs word_diff_minus |
260 (auto simp: word_arith_eqs word_diff_minus |
261 word_diff_self [unfolded word_diff_minus]) |
261 word_diff_self [unfolded word_diff_minus]) |
262 |
262 |
263 |
263 |
264 subsection "Order on fixed-length words" |
264 subsection "Order on fixed-length words" |
265 |
265 |
266 instance word :: (len0) ord |
266 instance word :: (type) ord |
267 word_le_def: "a <= b == uint a <= uint b" |
267 word_le_def: "a <= b == uint a <= uint b" |
268 word_less_def: "x < y == x <= y & x ~= y" |
268 word_less_def: "x < y == x <= y & x ~= y" |
269 .. |
269 .. |
270 |
270 |
271 constdefs |
271 constdefs |
272 word_sle :: "'a :: len word => 'a word => bool" ("(_/ <=s _)" [50, 51] 50) |
272 word_sle :: "'a :: finite word => 'a word => bool" ("(_/ <=s _)" [50, 51] 50) |
273 "a <=s b == sint a <= sint b" |
273 "a <=s b == sint a <= sint b" |
274 |
274 |
275 word_sless :: "'a :: len word => 'a word => bool" ("(_/ <s _)" [50, 51] 50) |
275 word_sless :: "'a :: finite word => 'a word => bool" ("(_/ <s _)" [50, 51] 50) |
276 "(x <s y) == (x <=s y & x ~= y)" |
276 "(x <s y) == (x <=s y & x ~= y)" |
277 |
277 |
278 lemma word_less_alt: "(a < b) = (uint a < uint b)" |
278 lemma word_less_alt: "(a < b) = (uint a < uint b)" |
279 unfolding word_less_def word_le_def |
279 unfolding word_less_def word_le_def |
280 by (auto simp del: word_uint.Rep_inject |
280 by (auto simp del: word_uint.Rep_inject |
298 word_sless_def [of "number_of ?a" "number_of ?b"] |
298 word_sless_def [of "number_of ?a" "number_of ?b"] |
299 |
299 |
300 lemmas word_sle_no [simp] = |
300 lemmas word_sle_no [simp] = |
301 word_sle_def [of "number_of ?a" "number_of ?b"] |
301 word_sle_def [of "number_of ?a" "number_of ?b"] |
302 |
302 |
303 lemma word_order_trans: "x <= y ==> y <= z ==> x <= (z :: 'a :: len0 word)" |
303 lemma word_order_trans: "x <= y ==> y <= z ==> x <= (z :: 'a word)" |
304 unfolding word_le_def by auto |
304 unfolding word_le_def by auto |
305 |
305 |
306 lemma word_order_refl: "z <= (z :: 'a :: len0 word)" |
306 lemma word_order_refl: "z <= (z :: 'a word)" |
307 unfolding word_le_def by auto |
307 unfolding word_le_def by auto |
308 |
308 |
309 lemma word_order_antisym: "x <= y ==> y <= x ==> x = (y :: 'a :: len0 word)" |
309 lemma word_order_antisym: "x <= y ==> y <= x ==> x = (y :: 'a word)" |
310 unfolding word_le_def by (auto intro!: word_uint.Rep_eqD) |
310 unfolding word_le_def by (auto intro!: word_uint.Rep_eqD) |
311 |
311 |
312 lemma word_order_linear: |
312 lemma word_order_linear: |
313 "y <= x | x <= (y :: 'a :: len0 word)" |
313 "y <= x | x <= (y :: 'a word)" |
314 unfolding word_le_def by auto |
314 unfolding word_le_def by auto |
315 |
315 |
316 lemma word_zero_le [simp] : |
316 lemma word_zero_le [simp] : |
317 "0 <= (y :: 'a :: len0 word)" |
317 "0 <= (y :: 'a word)" |
318 unfolding word_le_def by auto |
318 unfolding word_le_def by auto |
319 |
319 |
320 instance word :: (len0) linorder |
320 instance word :: (type) linorder |
321 by intro_classes (auto simp: word_less_def word_le_def) |
321 by intro_classes (auto simp: word_less_def word_le_def) |
322 |
322 |
323 lemma word_m1_ge [simp] : "word_pred 0 >= y" |
323 lemma word_m1_ge [simp] : "word_pred 0 >= y" |
324 unfolding word_le_def |
324 unfolding word_le_def |
325 by (simp only : word_pred_0_n1 word_uint.eq_norm m1mod2k) auto |
325 by (simp only : word_pred_0_n1 word_uint.eq_norm m1mod2k) auto |
345 lemma word_less_nat_alt: "(a < b) = (unat a < unat b)" |
345 lemma word_less_nat_alt: "(a < b) = (unat a < unat b)" |
346 unfolding unat_def word_less_alt |
346 unfolding unat_def word_less_alt |
347 by (rule nat_less_eq_zless [symmetric]) simp |
347 by (rule nat_less_eq_zless [symmetric]) simp |
348 |
348 |
349 lemma wi_less: |
349 lemma wi_less: |
350 "(word_of_int n < (word_of_int m :: 'a :: len0 word)) = |
350 "(word_of_int n < (word_of_int m :: 'a word)) = |
351 (n mod 2 ^ len_of TYPE('a) < m mod 2 ^ len_of TYPE('a))" |
351 (n mod 2 ^ CARD('a) < m mod 2 ^ CARD('a))" |
352 unfolding word_less_alt by (simp add: word_uint.eq_norm) |
352 unfolding word_less_alt by (simp add: word_uint.eq_norm) |
353 |
353 |
354 lemma wi_le: |
354 lemma wi_le: |
355 "(word_of_int n <= (word_of_int m :: 'a :: len0 word)) = |
355 "(word_of_int n <= (word_of_int m :: 'a word)) = |
356 (n mod 2 ^ len_of TYPE('a) <= m mod 2 ^ len_of TYPE('a))" |
356 (n mod 2 ^ CARD('a) <= m mod 2 ^ CARD('a))" |
357 unfolding word_le_def by (simp add: word_uint.eq_norm) |
357 unfolding word_le_def by (simp add: word_uint.eq_norm) |
358 |
358 |
359 lemmas unat_mono = word_less_nat_alt [THEN iffD1, standard] |
359 lemmas unat_mono = word_less_nat_alt [THEN iffD1, standard] |
360 |
360 |
361 |
361 |
362 subsection "Divisibility" |
362 subsection "Divisibility" |
363 |
363 |
364 definition |
364 definition |
365 udvd :: "'a::len word \<Rightarrow> 'a word \<Rightarrow> bool" (infixl "udvd" 50) where |
365 udvd :: "'a::finite word \<Rightarrow> 'a word \<Rightarrow> bool" (infixl "udvd" 50) where |
366 "a udvd b \<equiv> \<exists>n\<ge>0. uint b = n * uint a" |
366 "a udvd b \<equiv> \<exists>n\<ge>0. uint b = n * uint a" |
367 |
367 |
368 lemma udvdI: |
368 lemma udvdI: |
369 "0 \<le> n ==> uint b = n * uint a ==> a udvd b" |
369 "0 \<le> n ==> uint b = n * uint a ==> a udvd b" |
370 by (auto simp: udvd_def) |
370 by (auto simp: udvd_def) |
403 [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard] |
403 [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard] |
404 lemmas uint_mod_alt = word_mod_def |
404 lemmas uint_mod_alt = word_mod_def |
405 [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard] |
405 [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard] |
406 |
406 |
407 |
407 |
408 lemma word_zero_neq_one: "0 < len_of TYPE ('a :: len0) ==> (0 :: 'a word) ~= 1"; |
408 lemma word_zero_neq_one: "0 < CARD('a) ==> (0 :: 'a word) ~= 1"; |
409 unfolding word_arith_wis |
409 unfolding word_arith_wis |
410 by (auto simp add: word_ubin.norm_eq_iff [symmetric] gr0_conv_Suc) |
410 by (auto simp add: word_ubin.norm_eq_iff [symmetric] gr0_conv_Suc) |
411 |
411 |
412 lemmas lenw1_zero_neq_one = len_gt_0 [THEN word_zero_neq_one] |
412 lemmas lenw1_zero_neq_one = zero_less_card_finite [THEN word_zero_neq_one] |
413 |
413 |
414 lemma no_no [simp] : "number_of (number_of b) = number_of b" |
414 lemma no_no [simp] : "number_of (number_of b) = number_of b" |
415 by (simp add: number_of_eq) |
415 by (simp add: number_of_eq) |
416 |
416 |
417 lemma unat_minus_one: "x ~= 0 ==> unat (x - 1) = unat x - 1" |
417 lemma unat_minus_one: "x ~= 0 ==> unat (x - 1) = unat x - 1" |
443 add_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard] |
443 add_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard] |
444 lemmas uint_mult_ge0 [simp] = |
444 lemmas uint_mult_ge0 [simp] = |
445 mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard] |
445 mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard] |
446 |
446 |
447 lemma uint_sub_lt2p [simp]: |
447 lemma uint_sub_lt2p [simp]: |
448 "uint (x :: 'a :: len0 word) - uint (y :: 'b :: len0 word) < |
448 "uint (x :: 'a word) - uint (y :: 'b word) < |
449 2 ^ len_of TYPE('a)" |
449 2 ^ CARD('a)" |
450 using uint_ge_0 [of y] uint_lt2p [of x] by arith |
450 using uint_ge_0 [of y] uint_lt2p [of x] by arith |
451 |
451 |
452 |
452 |
453 subsection "Conditions for the addition (etc) of two words to overflow" |
453 subsection "Conditions for the addition (etc) of two words to overflow" |
454 |
454 |
455 lemma uint_add_lem: |
455 lemma uint_add_lem: |
456 "(uint x + uint y < 2 ^ len_of TYPE('a)) = |
456 "(uint x + uint y < 2 ^ CARD('a)) = |
457 (uint (x + y :: 'a :: len0 word) = uint x + uint y)" |
457 (uint (x + y :: 'a word) = uint x + uint y)" |
458 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
458 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
459 |
459 |
460 lemma uint_mult_lem: |
460 lemma uint_mult_lem: |
461 "(uint x * uint y < 2 ^ len_of TYPE('a)) = |
461 "(uint x * uint y < 2 ^ CARD('a)) = |
462 (uint (x * y :: 'a :: len0 word) = uint x * uint y)" |
462 (uint (x * y :: 'a word) = uint x * uint y)" |
463 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
463 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
464 |
464 |
465 lemma uint_sub_lem: |
465 lemma uint_sub_lem: |
466 "(uint x >= uint y) = (uint (x - y) = uint x - uint y)" |
466 "(uint x >= uint y) = (uint (x - y) = uint x - uint y)" |
467 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
467 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
479 |
479 |
480 |
480 |
481 subsection {* Definition of uint\_arith *} |
481 subsection {* Definition of uint\_arith *} |
482 |
482 |
483 lemma word_of_int_inverse: |
483 lemma word_of_int_inverse: |
484 "word_of_int r = a ==> 0 <= r ==> r < 2 ^ len_of TYPE('a) ==> |
484 "word_of_int r = a ==> 0 <= r ==> r < 2 ^ CARD('a) ==> |
485 uint (a::'a::len0 word) = r" |
485 uint (a::'a word) = r" |
486 apply (erule word_uint.Abs_inverse' [rotated]) |
486 apply (erule word_uint.Abs_inverse' [rotated]) |
487 apply (simp add: uints_num) |
487 apply (simp add: uints_num) |
488 done |
488 done |
489 |
489 |
490 lemma uint_split: |
490 lemma uint_split: |
491 fixes x::"'a::len0 word" |
491 fixes x::"'a word" |
492 shows "P (uint x) = |
492 shows "P (uint x) = |
493 (ALL i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) --> P i)" |
493 (ALL i. word_of_int i = x & 0 <= i & i < 2^CARD('a) --> P i)" |
494 apply (fold word_int_case_def) |
494 apply (fold word_int_case_def) |
495 apply (auto dest!: word_of_int_inverse simp: int_word_uint int_mod_eq' |
495 apply (auto dest!: word_of_int_inverse simp: int_word_uint int_mod_eq' |
496 split: word_int_split) |
496 split: word_int_split) |
497 done |
497 done |
498 |
498 |
499 lemma uint_split_asm: |
499 lemma uint_split_asm: |
500 fixes x::"'a::len0 word" |
500 fixes x::"'a word" |
501 shows "P (uint x) = |
501 shows "P (uint x) = |
502 (~(EX i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) & ~ P i))" |
502 (~(EX i. word_of_int i = x & 0 <= i & i < 2^CARD('a) & ~ P i))" |
503 by (auto dest!: word_of_int_inverse |
503 by (auto dest!: word_of_int_inverse |
504 simp: int_word_uint int_mod_eq' |
504 simp: int_word_uint int_mod_eq' |
505 split: uint_split) |
505 split: uint_split) |
506 |
506 |
507 lemmas uint_splits = uint_split uint_split_asm |
507 lemmas uint_splits = uint_split uint_split_asm |
548 |
548 |
549 |
549 |
550 subsection "More on overflows and monotonicity" |
550 subsection "More on overflows and monotonicity" |
551 |
551 |
552 lemma no_plus_overflow_uint_size: |
552 lemma no_plus_overflow_uint_size: |
553 "((x :: 'a :: len0 word) <= x + y) = (uint x + uint y < 2 ^ size x)" |
553 "((x :: 'a word) <= x + y) = (uint x + uint y < 2 ^ size x)" |
554 unfolding word_size by uint_arith |
554 unfolding word_size by uint_arith |
555 |
555 |
556 lemmas no_olen_add = no_plus_overflow_uint_size [unfolded word_size] |
556 lemmas no_olen_add = no_plus_overflow_uint_size [unfolded word_size] |
557 |
557 |
558 lemma no_ulen_sub: "((x :: 'a :: len0 word) >= x - y) = (uint y <= uint x)" |
558 lemma no_ulen_sub: "((x :: 'a word) >= x - y) = (uint y <= uint x)" |
559 by uint_arith |
559 by uint_arith |
560 |
560 |
561 lemma no_olen_add': |
561 lemma no_olen_add': |
562 fixes x :: "'a::len0 word" |
562 fixes x :: "'a word" |
563 shows "(x \<le> y + x) = (uint y + uint x < 2 ^ len_of TYPE('a))" |
563 shows "(x \<le> y + x) = (uint y + uint x < 2 ^ CARD('a))" |
564 by (simp add: word_add_ac add_ac no_olen_add) |
564 by (simp add: word_add_ac add_ac no_olen_add) |
565 |
565 |
566 lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric], standard] |
566 lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric], standard] |
567 |
567 |
568 lemmas uint_plus_simple_iff = trans [OF no_olen_add uint_add_lem, standard] |
568 lemmas uint_plus_simple_iff = trans [OF no_olen_add uint_add_lem, standard] |
571 lemmas uint_minus_simple_alt = uint_sub_lem [folded word_le_def] |
571 lemmas uint_minus_simple_alt = uint_sub_lem [folded word_le_def] |
572 lemmas word_sub_le_iff = no_ulen_sub [folded word_le_def] |
572 lemmas word_sub_le_iff = no_ulen_sub [folded word_le_def] |
573 lemmas word_sub_le = word_sub_le_iff [THEN iffD2, standard] |
573 lemmas word_sub_le = word_sub_le_iff [THEN iffD2, standard] |
574 |
574 |
575 lemma word_less_sub1: |
575 lemma word_less_sub1: |
576 "(x :: 'a :: len word) ~= 0 ==> (1 < x) = (0 < x - 1)" |
576 "(x :: 'a :: finite word) ~= 0 ==> (1 < x) = (0 < x - 1)" |
577 by uint_arith |
577 by uint_arith |
578 |
578 |
579 lemma word_le_sub1: |
579 lemma word_le_sub1: |
580 "(x :: 'a :: len word) ~= 0 ==> (1 <= x) = (0 <= x - 1)" |
580 "(x :: 'a :: finite word) ~= 0 ==> (1 <= x) = (0 <= x - 1)" |
581 by uint_arith |
581 by uint_arith |
582 |
582 |
583 lemma sub_wrap_lt: |
583 lemma sub_wrap_lt: |
584 "((x :: 'a :: len0 word) < x - z) = (x < z)" |
584 "((x :: 'a word) < x - z) = (x < z)" |
585 by uint_arith |
585 by uint_arith |
586 |
586 |
587 lemma sub_wrap: |
587 lemma sub_wrap: |
588 "((x :: 'a :: len0 word) <= x - z) = (z = 0 | x < z)" |
588 "((x :: 'a word) <= x - z) = (z = 0 | x < z)" |
589 by uint_arith |
589 by uint_arith |
590 |
590 |
591 lemma plus_minus_not_NULL_ab: |
591 lemma plus_minus_not_NULL_ab: |
592 "(x :: 'a :: len0 word) <= ab - c ==> c <= ab ==> c ~= 0 ==> x + c ~= 0" |
592 "(x :: 'a word) <= ab - c ==> c <= ab ==> c ~= 0 ==> x + c ~= 0" |
593 by uint_arith |
593 by uint_arith |
594 |
594 |
595 lemma plus_minus_no_overflow_ab: |
595 lemma plus_minus_no_overflow_ab: |
596 "(x :: 'a :: len0 word) <= ab - c ==> c <= ab ==> x <= x + c" |
596 "(x :: 'a word) <= ab - c ==> c <= ab ==> x <= x + c" |
597 by uint_arith |
597 by uint_arith |
598 |
598 |
599 lemma le_minus': |
599 lemma le_minus': |
600 "(a :: 'a :: len0 word) + c <= b ==> a <= a + c ==> c <= b - a" |
600 "(a :: 'a word) + c <= b ==> a <= a + c ==> c <= b - a" |
601 by uint_arith |
601 by uint_arith |
602 |
602 |
603 lemma le_plus': |
603 lemma le_plus': |
604 "(a :: 'a :: len0 word) <= b ==> c <= b - a ==> a + c <= b" |
604 "(a :: 'a word) <= b ==> c <= b - a ==> a + c <= b" |
605 by uint_arith |
605 by uint_arith |
606 |
606 |
607 lemmas le_plus = le_plus' [rotated] |
607 lemmas le_plus = le_plus' [rotated] |
608 |
608 |
609 lemmas le_minus = leD [THEN thin_rl, THEN le_minus', standard] |
609 lemmas le_minus = leD [THEN thin_rl, THEN le_minus', standard] |
610 |
610 |
611 lemma word_plus_mono_right: |
611 lemma word_plus_mono_right: |
612 "(y :: 'a :: len0 word) <= z ==> x <= x + z ==> x + y <= x + z" |
612 "(y :: 'a word) <= z ==> x <= x + z ==> x + y <= x + z" |
613 by uint_arith |
613 by uint_arith |
614 |
614 |
615 lemma word_less_minus_cancel: |
615 lemma word_less_minus_cancel: |
616 "y - x < z - x ==> x <= z ==> (y :: 'a :: len0 word) < z" |
616 "y - x < z - x ==> x <= z ==> (y :: 'a word) < z" |
617 by uint_arith |
617 by uint_arith |
618 |
618 |
619 lemma word_less_minus_mono_left: |
619 lemma word_less_minus_mono_left: |
620 "(y :: 'a :: len0 word) < z ==> x <= y ==> y - x < z - x" |
620 "(y :: 'a word) < z ==> x <= y ==> y - x < z - x" |
621 by uint_arith |
621 by uint_arith |
622 |
622 |
623 lemma word_less_minus_mono: |
623 lemma word_less_minus_mono: |
624 "a < c ==> d < b ==> a - b < a ==> c - d < c |
624 "a < c ==> d < b ==> a - b < a ==> c - d < c |
625 ==> a - b < c - (d::'a::len word)" |
625 ==> a - b < c - (d::'a::finite word)" |
626 by uint_arith |
626 by uint_arith |
627 |
627 |
628 lemma word_le_minus_cancel: |
628 lemma word_le_minus_cancel: |
629 "y - x <= z - x ==> x <= z ==> (y :: 'a :: len0 word) <= z" |
629 "y - x <= z - x ==> x <= z ==> (y :: 'a word) <= z" |
630 by uint_arith |
630 by uint_arith |
631 |
631 |
632 lemma word_le_minus_mono_left: |
632 lemma word_le_minus_mono_left: |
633 "(y :: 'a :: len0 word) <= z ==> x <= y ==> y - x <= z - x" |
633 "(y :: 'a word) <= z ==> x <= y ==> y - x <= z - x" |
634 by uint_arith |
634 by uint_arith |
635 |
635 |
636 lemma word_le_minus_mono: |
636 lemma word_le_minus_mono: |
637 "a <= c ==> d <= b ==> a - b <= a ==> c - d <= c |
637 "a <= c ==> d <= b ==> a - b <= a ==> c - d <= c |
638 ==> a - b <= c - (d::'a::len word)" |
638 ==> a - b <= c - (d::'a::finite word)" |
639 by uint_arith |
639 by uint_arith |
640 |
640 |
641 lemma plus_le_left_cancel_wrap: |
641 lemma plus_le_left_cancel_wrap: |
642 "(x :: 'a :: len0 word) + y' < x ==> x + y < x ==> (x + y' < x + y) = (y' < y)" |
642 "(x :: 'a word) + y' < x ==> x + y < x ==> (x + y' < x + y) = (y' < y)" |
643 by uint_arith |
643 by uint_arith |
644 |
644 |
645 lemma plus_le_left_cancel_nowrap: |
645 lemma plus_le_left_cancel_nowrap: |
646 "(x :: 'a :: len0 word) <= x + y' ==> x <= x + y ==> |
646 "(x :: 'a word) <= x + y' ==> x <= x + y ==> |
647 (x + y' < x + y) = (y' < y)" |
647 (x + y' < x + y) = (y' < y)" |
648 by uint_arith |
648 by uint_arith |
649 |
649 |
650 lemma word_plus_mono_right2: |
650 lemma word_plus_mono_right2: |
651 "(a :: 'a :: len0 word) <= a + b ==> c <= b ==> a <= a + c" |
651 "(a :: 'a word) <= a + b ==> c <= b ==> a <= a + c" |
652 by uint_arith |
652 by uint_arith |
653 |
653 |
654 lemma word_less_add_right: |
654 lemma word_less_add_right: |
655 "(x :: 'a :: len0 word) < y - z ==> z <= y ==> x + z < y" |
655 "(x :: 'a word) < y - z ==> z <= y ==> x + z < y" |
656 by uint_arith |
656 by uint_arith |
657 |
657 |
658 lemma word_less_sub_right: |
658 lemma word_less_sub_right: |
659 "(x :: 'a :: len0 word) < y + z ==> y <= x ==> x - y < z" |
659 "(x :: 'a word) < y + z ==> y <= x ==> x - y < z" |
660 by uint_arith |
660 by uint_arith |
661 |
661 |
662 lemma word_le_plus_either: |
662 lemma word_le_plus_either: |
663 "(x :: 'a :: len0 word) <= y | x <= z ==> y <= y + z ==> x <= y + z" |
663 "(x :: 'a word) <= y | x <= z ==> y <= y + z ==> x <= y + z" |
664 by uint_arith |
664 by uint_arith |
665 |
665 |
666 lemma word_less_nowrapI: |
666 lemma word_less_nowrapI: |
667 "(x :: 'a :: len0 word) < z - k ==> k <= z ==> 0 < k ==> x < x + k" |
667 "(x :: 'a word) < z - k ==> k <= z ==> 0 < k ==> x < x + k" |
668 by uint_arith |
668 by uint_arith |
669 |
669 |
670 lemma inc_le: "(i :: 'a :: len word) < m ==> i + 1 <= m" |
670 lemma inc_le: "(i :: 'a :: finite word) < m ==> i + 1 <= m" |
671 by uint_arith |
671 by uint_arith |
672 |
672 |
673 lemma inc_i: |
673 lemma inc_i: |
674 "(1 :: 'a :: len word) <= i ==> i < m ==> 1 <= (i + 1) & i + 1 <= m" |
674 "(1 :: 'a :: finite word) <= i ==> i < m ==> 1 <= (i + 1) & i + 1 <= m" |
675 by uint_arith |
675 by uint_arith |
676 |
676 |
677 lemma udvd_incr_lem: |
677 lemma udvd_incr_lem: |
678 "up < uq ==> up = ua + n * uint K ==> |
678 "up < uq ==> up = ua + n * uint K ==> |
679 uq = ua + n' * uint K ==> up + uint K <= uq" |
679 uq = ua + n' * uint K ==> up + uint K <= uq" |
727 apply simp |
727 apply simp |
728 done |
728 done |
729 |
729 |
730 subsection "Arithmetic type class instantiations" |
730 subsection "Arithmetic type class instantiations" |
731 |
731 |
732 instance word :: (len0) comm_monoid_add .. |
732 instance word :: (type) comm_monoid_add .. |
733 |
733 |
734 instance word :: (len0) comm_monoid_mult |
734 instance word :: (type) comm_monoid_mult |
735 apply (intro_classes) |
735 apply (intro_classes) |
736 apply (simp add: word_mult_commute) |
736 apply (simp add: word_mult_commute) |
737 apply (simp add: word_mult_1) |
737 apply (simp add: word_mult_1) |
738 done |
738 done |
739 |
739 |
740 instance word :: (len0) comm_semiring |
740 instance word :: (type) comm_semiring |
741 by (intro_classes) (simp add : word_left_distrib) |
741 by (intro_classes) (simp add : word_left_distrib) |
742 |
742 |
743 instance word :: (len0) ab_group_add .. |
743 instance word :: (type) ab_group_add .. |
744 |
744 |
745 instance word :: (len0) comm_ring .. |
745 instance word :: (type) comm_ring .. |
746 |
746 |
747 instance word :: (len) comm_semiring_1 |
747 instance word :: (finite) comm_semiring_1 |
748 by (intro_classes) (simp add: lenw1_zero_neq_one) |
748 by (intro_classes) (simp add: lenw1_zero_neq_one) |
749 |
749 |
750 instance word :: (len) comm_ring_1 .. |
750 instance word :: (finite) comm_ring_1 .. |
751 |
751 |
752 instance word :: (len0) comm_semiring_0 .. |
752 instance word :: (type) comm_semiring_0 .. |
753 |
753 |
754 instance word :: (len) recpower |
754 instance word :: (finite) recpower |
755 by (intro_classes) (simp_all add: word_pow) |
755 by (intro_classes) (simp_all add: word_pow) |
756 |
756 |
757 (* note that iszero_def is only for class comm_semiring_1_cancel, |
757 (* note that iszero_def is only for class comm_semiring_1_cancel, |
758 which requires word length >= 1, ie 'a :: len word *) |
758 which requires word length >= 1, ie 'a :: finite word *) |
759 lemma zero_bintrunc: |
759 lemma zero_bintrunc: |
760 "iszero (number_of x :: 'a :: len word) = |
760 "iszero (number_of x :: 'a :: finite word) = |
761 (bintrunc (len_of TYPE('a)) x = Numeral.Pls)" |
761 (bintrunc CARD('a) x = Numeral.Pls)" |
762 apply (unfold iszero_def word_0_wi word_no_wi) |
762 apply (unfold iszero_def word_0_wi word_no_wi) |
763 apply (rule word_ubin.norm_eq_iff [symmetric, THEN trans]) |
763 apply (rule word_ubin.norm_eq_iff [symmetric, THEN trans]) |
764 apply (simp add : Pls_def [symmetric]) |
764 apply (simp add : Pls_def [symmetric]) |
765 done |
765 done |
766 |
766 |
779 lemma word_of_int_nat: |
779 lemma word_of_int_nat: |
780 "0 <= x ==> word_of_int x = of_nat (nat x)" |
780 "0 <= x ==> word_of_int x = of_nat (nat x)" |
781 by (simp add: of_nat_nat word_of_int) |
781 by (simp add: of_nat_nat word_of_int) |
782 |
782 |
783 lemma word_number_of_eq: |
783 lemma word_number_of_eq: |
784 "number_of w = (of_int w :: 'a :: len word)" |
784 "number_of w = (of_int w :: 'a :: finite word)" |
785 unfolding word_number_of_def word_of_int by auto |
785 unfolding word_number_of_def word_of_int by auto |
786 |
786 |
787 instance word :: (len) number_ring |
787 instance word :: (finite) number_ring |
788 by (intro_classes) (simp add : word_number_of_eq) |
788 by (intro_classes) (simp add : word_number_of_eq) |
789 |
789 |
790 lemma iszero_word_no [simp] : |
790 lemma iszero_word_no [simp] : |
791 "iszero (number_of bin :: 'a :: len word) = |
791 "iszero (number_of bin :: 'a :: finite word) = |
792 iszero (number_of (bintrunc (len_of TYPE('a)) bin) :: int)" |
792 iszero (number_of (bintrunc CARD('a) bin) :: int)" |
793 apply (simp add: zero_bintrunc number_of_is_id) |
793 apply (simp add: zero_bintrunc number_of_is_id) |
794 apply (unfold iszero_def Pls_def) |
794 apply (unfold iszero_def Pls_def) |
795 apply (rule refl) |
795 apply (rule refl) |
796 done |
796 done |
797 |
797 |
798 |
798 |
799 subsection "Word and nat" |
799 subsection "Word and nat" |
800 |
800 |
801 lemma td_ext_unat': |
801 lemma td_ext_unat': |
802 "n = len_of TYPE ('a :: len) ==> |
802 "n = CARD('a :: finite) ==> |
803 td_ext (unat :: 'a word => nat) of_nat |
803 td_ext (unat :: 'a word => nat) of_nat |
804 (unats n) (%i. i mod 2 ^ n)" |
804 (unats n) (%i. i mod 2 ^ n)" |
805 apply (unfold td_ext_def' unat_def word_of_nat unats_uints) |
805 apply (unfold td_ext_def' unat_def word_of_nat unats_uints) |
806 apply (auto intro!: imageI simp add : word_of_int_hom_syms) |
806 apply (auto intro!: imageI simp add : word_of_int_hom_syms) |
807 apply (erule word_uint.Abs_inverse [THEN arg_cong]) |
807 apply (erule word_uint.Abs_inverse [THEN arg_cong]) |
810 |
810 |
811 lemmas td_ext_unat = refl [THEN td_ext_unat'] |
811 lemmas td_ext_unat = refl [THEN td_ext_unat'] |
812 lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm, standard] |
812 lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm, standard] |
813 |
813 |
814 interpretation word_unat: |
814 interpretation word_unat: |
815 td_ext ["unat::'a::len word => nat" |
815 td_ext ["unat::'a::finite word => nat" |
816 of_nat |
816 of_nat |
817 "unats (len_of TYPE('a::len))" |
817 "unats CARD('a::finite)" |
818 "%i. i mod 2 ^ len_of TYPE('a::len)"] |
818 "%i. i mod 2 ^ CARD('a::finite)"] |
819 by (rule td_ext_unat) |
819 by (rule td_ext_unat) |
820 |
820 |
821 lemmas td_unat = word_unat.td_thm |
821 lemmas td_unat = word_unat.td_thm |
822 |
822 |
823 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq] |
823 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq] |
824 |
824 |
825 lemma unat_le: "y <= unat (z :: 'a :: len word) ==> y : unats (len_of TYPE ('a))" |
825 lemma unat_le: "y <= unat (z :: 'a :: finite word) ==> y : unats CARD('a)" |
826 apply (unfold unats_def) |
826 apply (unfold unats_def) |
827 apply clarsimp |
827 apply clarsimp |
828 apply (rule xtrans, rule unat_lt2p, assumption) |
828 apply (rule xtrans, rule unat_lt2p, assumption) |
829 done |
829 done |
830 |
830 |
831 lemma word_nchotomy: |
831 lemma word_nchotomy: |
832 "ALL w. EX n. (w :: 'a :: len word) = of_nat n & n < 2 ^ len_of TYPE ('a)" |
832 "ALL w. EX n. (w :: 'a :: finite word) = of_nat n & n < 2 ^ CARD('a)" |
833 apply (rule allI) |
833 apply (rule allI) |
834 apply (rule word_unat.Abs_cases) |
834 apply (rule word_unat.Abs_cases) |
835 apply (unfold unats_def) |
835 apply (unfold unats_def) |
836 apply auto |
836 apply auto |
837 done |
837 done |
838 |
838 |
839 lemma of_nat_eq: |
839 lemma of_nat_eq: |
840 fixes w :: "'a::len word" |
840 fixes w :: "'a::finite word" |
841 shows "(of_nat n = w) = (\<exists>q. n = unat w + q * 2 ^ len_of TYPE('a))" |
841 shows "(of_nat n = w) = (\<exists>q. n = unat w + q * 2 ^ CARD('a))" |
842 apply (rule trans) |
842 apply (rule trans) |
843 apply (rule word_unat.inverse_norm) |
843 apply (rule word_unat.inverse_norm) |
844 apply (rule iffI) |
844 apply (rule iffI) |
845 apply (rule mod_eqD) |
845 apply (rule mod_eqD) |
846 apply simp |
846 apply simp |
850 lemma of_nat_eq_size: |
850 lemma of_nat_eq_size: |
851 "(of_nat n = w) = (EX q. n = unat w + q * 2 ^ size w)" |
851 "(of_nat n = w) = (EX q. n = unat w + q * 2 ^ size w)" |
852 unfolding word_size by (rule of_nat_eq) |
852 unfolding word_size by (rule of_nat_eq) |
853 |
853 |
854 lemma of_nat_0: |
854 lemma of_nat_0: |
855 "(of_nat m = (0::'a::len word)) = (\<exists>q. m = q * 2 ^ len_of TYPE('a))" |
855 "(of_nat m = (0::'a::finite word)) = (\<exists>q. m = q * 2 ^ CARD('a))" |
856 by (simp add: of_nat_eq) |
856 by (simp add: of_nat_eq) |
857 |
857 |
858 lemmas of_nat_2p = mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]] |
858 lemmas of_nat_2p = mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]] |
859 |
859 |
860 lemma of_nat_gt_0: "of_nat k ~= 0 ==> 0 < k" |
860 lemma of_nat_gt_0: "of_nat k ~= 0 ==> 0 < k" |
861 by (cases k) auto |
861 by (cases k) auto |
862 |
862 |
863 lemma of_nat_neq_0: |
863 lemma of_nat_neq_0: |
864 "0 < k ==> k < 2 ^ len_of TYPE ('a :: len) ==> of_nat k ~= (0 :: 'a word)" |
864 "0 < k ==> k < 2 ^ CARD('a :: finite) ==> of_nat k ~= (0 :: 'a word)" |
865 by (clarsimp simp add : of_nat_0) |
865 by (clarsimp simp add : of_nat_0) |
866 |
866 |
867 lemma Abs_fnat_hom_add: |
867 lemma Abs_fnat_hom_add: |
868 "of_nat a + of_nat b = of_nat (a + b)" |
868 "of_nat a + of_nat b = of_nat (a + b)" |
869 by simp |
869 by simp |
870 |
870 |
871 lemma Abs_fnat_hom_mult: |
871 lemma Abs_fnat_hom_mult: |
872 "of_nat a * of_nat b = (of_nat (a * b) :: 'a :: len word)" |
872 "of_nat a * of_nat b = (of_nat (a * b) :: 'a :: finite word)" |
873 by (simp add: word_of_nat word_of_int_mult_hom zmult_int) |
873 by (simp add: word_of_nat word_of_int_mult_hom zmult_int) |
874 |
874 |
875 lemma Abs_fnat_hom_Suc: |
875 lemma Abs_fnat_hom_Suc: |
876 "word_succ (of_nat a) = of_nat (Suc a)" |
876 "word_succ (of_nat a) = of_nat (Suc a)" |
877 by (simp add: word_of_nat word_of_int_succ_hom add_ac) |
877 by (simp add: word_of_nat word_of_int_succ_hom add_ac) |
878 |
878 |
879 lemma Abs_fnat_hom_0: "(0::'a::len word) = of_nat 0" |
879 lemma Abs_fnat_hom_0: "(0::'a::finite word) = of_nat 0" |
880 by (simp add: word_of_nat word_0_wi) |
880 by (simp add: word_of_nat word_0_wi) |
881 |
881 |
882 lemma Abs_fnat_hom_1: "(1::'a::len word) = of_nat (Suc 0)" |
882 lemma Abs_fnat_hom_1: "(1::'a::finite word) = of_nat (Suc 0)" |
883 by (simp add: word_of_nat word_1_wi) |
883 by (simp add: word_of_nat word_1_wi) |
884 |
884 |
885 lemmas Abs_fnat_homs = |
885 lemmas Abs_fnat_homs = |
886 Abs_fnat_hom_add Abs_fnat_hom_mult Abs_fnat_hom_Suc |
886 Abs_fnat_hom_add Abs_fnat_hom_mult Abs_fnat_hom_Suc |
887 Abs_fnat_hom_0 Abs_fnat_hom_1 |
887 Abs_fnat_hom_0 Abs_fnat_hom_1 |
919 |
919 |
920 lemmas word_sub_less_iff = word_sub_le_iff |
920 lemmas word_sub_less_iff = word_sub_le_iff |
921 [simplified linorder_not_less [symmetric], simplified] |
921 [simplified linorder_not_less [symmetric], simplified] |
922 |
922 |
923 lemma unat_add_lem: |
923 lemma unat_add_lem: |
924 "(unat x + unat y < 2 ^ len_of TYPE('a)) = |
924 "(unat x + unat y < 2 ^ CARD('a)) = |
925 (unat (x + y :: 'a :: len word) = unat x + unat y)" |
925 (unat (x + y :: 'a :: finite word) = unat x + unat y)" |
926 unfolding unat_word_ariths |
926 unfolding unat_word_ariths |
927 by (auto intro!: trans [OF _ nat_mod_lem]) |
927 by (auto intro!: trans [OF _ nat_mod_lem]) |
928 |
928 |
929 lemma unat_mult_lem: |
929 lemma unat_mult_lem: |
930 "(unat x * unat y < 2 ^ len_of TYPE('a)) = |
930 "(unat x * unat y < 2 ^ CARD('a)) = |
931 (unat (x * y :: 'a :: len word) = unat x * unat y)" |
931 (unat (x * y :: 'a :: finite word) = unat x * unat y)" |
932 unfolding unat_word_ariths |
932 unfolding unat_word_ariths |
933 by (auto intro!: trans [OF _ nat_mod_lem]) |
933 by (auto intro!: trans [OF _ nat_mod_lem]) |
934 |
934 |
935 lemmas unat_plus_if' = |
935 lemmas unat_plus_if' = |
936 trans [OF unat_word_ariths(1) mod_nat_add, simplified, standard] |
936 trans [OF unat_word_ariths(1) mod_nat_add, simplified, standard] |
937 |
937 |
938 lemma le_no_overflow: |
938 lemma le_no_overflow: |
939 "x <= b ==> a <= a + b ==> x <= a + (b :: 'a :: len0 word)" |
939 "x <= b ==> a <= a + b ==> x <= a + (b :: 'a word)" |
940 apply (erule order_trans) |
940 apply (erule order_trans) |
941 apply (erule olen_add_eqv [THEN iffD1]) |
941 apply (erule olen_add_eqv [THEN iffD1]) |
942 done |
942 done |
943 |
943 |
944 lemmas un_ui_le = trans |
944 lemmas un_ui_le = trans |
965 apply uint_arith |
965 apply uint_arith |
966 done |
966 done |
967 |
967 |
968 lemmas unat_sub_if' = unat_sub_if_size [unfolded word_size] |
968 lemmas unat_sub_if' = unat_sub_if_size [unfolded word_size] |
969 |
969 |
970 lemma unat_div: "unat ((x :: 'a :: len word) div y) = unat x div unat y" |
970 lemma unat_div: "unat ((x :: 'a :: finite word) div y) = unat x div unat y" |
971 apply (simp add : unat_word_ariths) |
971 apply (simp add : unat_word_ariths) |
972 apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq']) |
972 apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq']) |
973 apply (rule div_le_dividend) |
973 apply (rule div_le_dividend) |
974 done |
974 done |
975 |
975 |
976 lemma unat_mod: "unat ((x :: 'a :: len word) mod y) = unat x mod unat y" |
976 lemma unat_mod: "unat ((x :: 'a :: finite word) mod y) = unat x mod unat y" |
977 apply (clarsimp simp add : unat_word_ariths) |
977 apply (clarsimp simp add : unat_word_ariths) |
978 apply (cases "unat y") |
978 apply (cases "unat y") |
979 prefer 2 |
979 prefer 2 |
980 apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq']) |
980 apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq']) |
981 apply (rule mod_le_divisor) |
981 apply (rule mod_le_divisor) |
982 apply auto |
982 apply auto |
983 done |
983 done |
984 |
984 |
985 lemma uint_div: "uint ((x :: 'a :: len word) div y) = uint x div uint y" |
985 lemma uint_div: "uint ((x :: 'a :: finite word) div y) = uint x div uint y" |
986 unfolding uint_nat by (simp add : unat_div zdiv_int) |
986 unfolding uint_nat by (simp add : unat_div zdiv_int) |
987 |
987 |
988 lemma uint_mod: "uint ((x :: 'a :: len word) mod y) = uint x mod uint y" |
988 lemma uint_mod: "uint ((x :: 'a :: finite word) mod y) = uint x mod uint y" |
989 unfolding uint_nat by (simp add : unat_mod zmod_int) |
989 unfolding uint_nat by (simp add : unat_mod zmod_int) |
990 |
990 |
991 |
991 |
992 subsection {* Definition of unat\_arith tactic *} |
992 subsection {* Definition of unat\_arith tactic *} |
993 |
993 |
994 lemma unat_split: |
994 lemma unat_split: |
995 fixes x::"'a::len word" |
995 fixes x::"'a::finite word" |
996 shows "P (unat x) = |
996 shows "P (unat x) = |
997 (ALL n. of_nat n = x & n < 2^len_of TYPE('a) --> P n)" |
997 (ALL n. of_nat n = x & n < 2^CARD('a) --> P n)" |
998 by (auto simp: unat_of_nat) |
998 by (auto simp: unat_of_nat) |
999 |
999 |
1000 lemma unat_split_asm: |
1000 lemma unat_split_asm: |
1001 fixes x::"'a::len word" |
1001 fixes x::"'a::finite word" |
1002 shows "P (unat x) = |
1002 shows "P (unat x) = |
1003 (~(EX n. of_nat n = x & n < 2^len_of TYPE('a) & ~ P n))" |
1003 (~(EX n. of_nat n = x & n < 2^CARD('a) & ~ P n))" |
1004 by (auto simp: unat_of_nat) |
1004 by (auto simp: unat_of_nat) |
1005 |
1005 |
1006 lemmas of_nat_inverse = |
1006 lemmas of_nat_inverse = |
1007 word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified] |
1007 word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified] |
1008 |
1008 |
1042 method_setup unat_arith = |
1042 method_setup unat_arith = |
1043 "Method.ctxt_args (fn ctxt => Method.SIMPLE_METHOD (unat_arith_tac ctxt 1))" |
1043 "Method.ctxt_args (fn ctxt => Method.SIMPLE_METHOD (unat_arith_tac ctxt 1))" |
1044 "solving word arithmetic via natural numbers and arith" |
1044 "solving word arithmetic via natural numbers and arith" |
1045 |
1045 |
1046 lemma no_plus_overflow_unat_size: |
1046 lemma no_plus_overflow_unat_size: |
1047 "((x :: 'a :: len word) <= x + y) = (unat x + unat y < 2 ^ size x)" |
1047 "((x :: 'a :: finite word) <= x + y) = (unat x + unat y < 2 ^ size x)" |
1048 unfolding word_size by unat_arith |
1048 unfolding word_size by unat_arith |
1049 |
1049 |
1050 lemma unat_sub: "b <= a ==> unat (a - b) = unat a - unat (b :: 'a :: len word)" |
1050 lemma unat_sub: "b <= a ==> unat (a - b) = unat a - unat (b :: 'a :: finite word)" |
1051 by unat_arith |
1051 by unat_arith |
1052 |
1052 |
1053 lemmas no_olen_add_nat = no_plus_overflow_unat_size [unfolded word_size] |
1053 lemmas no_olen_add_nat = no_plus_overflow_unat_size [unfolded word_size] |
1054 |
1054 |
1055 lemmas unat_plus_simple = trans [OF no_olen_add_nat unat_add_lem, standard] |
1055 lemmas unat_plus_simple = trans [OF no_olen_add_nat unat_add_lem, standard] |
1056 |
1056 |
1057 lemma word_div_mult: |
1057 lemma word_div_mult: |
1058 "(0 :: 'a :: len word) < y ==> unat x * unat y < 2 ^ len_of TYPE('a) ==> |
1058 "(0 :: 'a :: finite word) < y ==> unat x * unat y < 2 ^ CARD('a) ==> |
1059 x * y div y = x" |
1059 x * y div y = x" |
1060 apply unat_arith |
1060 apply unat_arith |
1061 apply clarsimp |
1061 apply clarsimp |
1062 apply (subst unat_mult_lem [THEN iffD1]) |
1062 apply (subst unat_mult_lem [THEN iffD1]) |
1063 apply auto |
1063 apply auto |
1064 done |
1064 done |
1065 |
1065 |
1066 lemma div_lt': "(i :: 'a :: len word) <= k div x ==> |
1066 lemma div_lt': "(i :: 'a :: finite word) <= k div x ==> |
1067 unat i * unat x < 2 ^ len_of TYPE('a)" |
1067 unat i * unat x < 2 ^ CARD('a)" |
1068 apply unat_arith |
1068 apply unat_arith |
1069 apply clarsimp |
1069 apply clarsimp |
1070 apply (drule mult_le_mono1) |
1070 apply (drule mult_le_mono1) |
1071 apply (erule order_le_less_trans) |
1071 apply (erule order_le_less_trans) |
1072 apply (rule xtr7 [OF unat_lt2p div_mult_le]) |
1072 apply (rule xtr7 [OF unat_lt2p div_mult_le]) |
1073 done |
1073 done |
1074 |
1074 |
1075 lemmas div_lt'' = order_less_imp_le [THEN div_lt'] |
1075 lemmas div_lt'' = order_less_imp_le [THEN div_lt'] |
1076 |
1076 |
1077 lemma div_lt_mult: "(i :: 'a :: len word) < k div x ==> 0 < x ==> i * x < k" |
1077 lemma div_lt_mult: "(i :: 'a :: finite word) < k div x ==> 0 < x ==> i * x < k" |
1078 apply (frule div_lt'' [THEN unat_mult_lem [THEN iffD1]]) |
1078 apply (frule div_lt'' [THEN unat_mult_lem [THEN iffD1]]) |
1079 apply (simp add: unat_arith_simps) |
1079 apply (simp add: unat_arith_simps) |
1080 apply (drule (1) mult_less_mono1) |
1080 apply (drule (1) mult_less_mono1) |
1081 apply (erule order_less_le_trans) |
1081 apply (erule order_less_le_trans) |
1082 apply (rule div_mult_le) |
1082 apply (rule div_mult_le) |
1083 done |
1083 done |
1084 |
1084 |
1085 lemma div_le_mult: |
1085 lemma div_le_mult: |
1086 "(i :: 'a :: len word) <= k div x ==> 0 < x ==> i * x <= k" |
1086 "(i :: 'a :: finite word) <= k div x ==> 0 < x ==> i * x <= k" |
1087 apply (frule div_lt' [THEN unat_mult_lem [THEN iffD1]]) |
1087 apply (frule div_lt' [THEN unat_mult_lem [THEN iffD1]]) |
1088 apply (simp add: unat_arith_simps) |
1088 apply (simp add: unat_arith_simps) |
1089 apply (drule mult_le_mono1) |
1089 apply (drule mult_le_mono1) |
1090 apply (erule order_trans) |
1090 apply (erule order_trans) |
1091 apply (rule div_mult_le) |
1091 apply (rule div_mult_le) |
1092 done |
1092 done |
1093 |
1093 |
1094 lemma div_lt_uint': |
1094 lemma div_lt_uint': |
1095 "(i :: 'a :: len word) <= k div x ==> uint i * uint x < 2 ^ len_of TYPE('a)" |
1095 "(i :: 'a :: finite word) <= k div x ==> uint i * uint x < 2 ^ CARD('a)" |
1096 apply (unfold uint_nat) |
1096 apply (unfold uint_nat) |
1097 apply (drule div_lt') |
1097 apply (drule div_lt') |
1098 apply (simp add: zmult_int zless_nat_eq_int_zless [symmetric] |
1098 apply (simp add: zmult_int zless_nat_eq_int_zless [symmetric] |
1099 nat_power_eq) |
1099 nat_power_eq) |
1100 done |
1100 done |
1101 |
1101 |
1102 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint'] |
1102 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint'] |
1103 |
1103 |
1104 lemma word_le_exists': |
1104 lemma word_le_exists': |
1105 "(x :: 'a :: len0 word) <= y ==> |
1105 "(x :: 'a word) <= y ==> |
1106 (EX z. y = x + z & uint x + uint z < 2 ^ len_of TYPE('a))" |
1106 (EX z. y = x + z & uint x + uint z < 2 ^ CARD('a))" |
1107 apply (rule exI) |
1107 apply (rule exI) |
1108 apply (rule conjI) |
1108 apply (rule conjI) |
1109 apply (rule zadd_diff_inverse) |
1109 apply (rule zadd_diff_inverse) |
1110 apply uint_arith |
1110 apply uint_arith |
1111 done |
1111 done |
1137 |
1137 |
1138 lemmas uno_simps [THEN le_unat_uoi, standard] = |
1138 lemmas uno_simps [THEN le_unat_uoi, standard] = |
1139 mod_le_divisor div_le_dividend thd1 |
1139 mod_le_divisor div_le_dividend thd1 |
1140 |
1140 |
1141 lemma word_mod_div_equality: |
1141 lemma word_mod_div_equality: |
1142 "(n div b) * b + (n mod b) = (n :: 'a :: len word)" |
1142 "(n div b) * b + (n mod b) = (n :: 'a :: finite word)" |
1143 apply (unfold word_less_nat_alt word_arith_nat_defs) |
1143 apply (unfold word_less_nat_alt word_arith_nat_defs) |
1144 apply (cut_tac y="unat b" in gt_or_eq_0) |
1144 apply (cut_tac y="unat b" in gt_or_eq_0) |
1145 apply (erule disjE) |
1145 apply (erule disjE) |
1146 apply (simp add: mod_div_equality uno_simps) |
1146 apply (simp add: mod_div_equality uno_simps) |
1147 apply simp |
1147 apply simp |
1148 done |
1148 done |
1149 |
1149 |
1150 lemma word_div_mult_le: "a div b * b <= (a::'a::len word)" |
1150 lemma word_div_mult_le: "a div b * b <= (a::'a::finite word)" |
1151 apply (unfold word_le_nat_alt word_arith_nat_defs) |
1151 apply (unfold word_le_nat_alt word_arith_nat_defs) |
1152 apply (cut_tac y="unat b" in gt_or_eq_0) |
1152 apply (cut_tac y="unat b" in gt_or_eq_0) |
1153 apply (erule disjE) |
1153 apply (erule disjE) |
1154 apply (simp add: div_mult_le uno_simps) |
1154 apply (simp add: div_mult_le uno_simps) |
1155 apply simp |
1155 apply simp |
1156 done |
1156 done |
1157 |
1157 |
1158 lemma word_mod_less_divisor: "0 < n ==> m mod n < (n :: 'a :: len word)" |
1158 lemma word_mod_less_divisor: "0 < n ==> m mod n < (n :: 'a :: finite word)" |
1159 apply (simp only: word_less_nat_alt word_arith_nat_defs) |
1159 apply (simp only: word_less_nat_alt word_arith_nat_defs) |
1160 apply (clarsimp simp add : uno_simps) |
1160 apply (clarsimp simp add : uno_simps) |
1161 done |
1161 done |
1162 |
1162 |
1163 lemma word_of_int_power_hom: |
1163 lemma word_of_int_power_hom: |
1164 "word_of_int a ^ n = (word_of_int (a ^ n) :: 'a :: len word)" |
1164 "word_of_int a ^ n = (word_of_int (a ^ n) :: 'a :: finite word)" |
1165 by (induct n) (simp_all add : word_of_int_hom_syms power_Suc) |
1165 by (induct n) (simp_all add : word_of_int_hom_syms power_Suc) |
1166 |
1166 |
1167 lemma word_arith_power_alt: |
1167 lemma word_arith_power_alt: |
1168 "a ^ n = (word_of_int (uint a ^ n) :: 'a :: len word)" |
1168 "a ^ n = (word_of_int (uint a ^ n) :: 'a :: finite word)" |
1169 by (simp add : word_of_int_power_hom [symmetric]) |
1169 by (simp add : word_of_int_power_hom [symmetric]) |
1170 |
1170 |
1171 |
1171 |
1172 subsection "Cardinality, finiteness of set of words" |
1172 subsection "Cardinality, finiteness of set of words" |
1173 |
1173 |
1176 lemmas card_eq = word_unat.Abs_inj_on [THEN card_image, |
1176 lemmas card_eq = word_unat.Abs_inj_on [THEN card_image, |
1177 unfolded word_unat.image, unfolded unats_def, standard] |
1177 unfolded word_unat.image, unfolded unats_def, standard] |
1178 |
1178 |
1179 lemmas card_word = trans [OF card_eq card_lessThan', standard] |
1179 lemmas card_word = trans [OF card_eq card_lessThan', standard] |
1180 |
1180 |
1181 lemma finite_word_UNIV: "finite (UNIV :: 'a :: len word set)" |
1181 lemma finite_word_UNIV: "finite (UNIV :: 'a :: finite word set)" |
1182 apply (rule contrapos_np) |
1182 apply (rule contrapos_np) |
1183 prefer 2 |
1183 prefer 2 |
1184 apply (erule card_infinite) |
1184 apply (erule card_infinite) |
1185 apply (simp add : card_word) |
1185 apply (simp add : card_word) |
1186 done |
1186 done |
1187 |
1187 |
1188 lemma card_word_size: |
1188 lemma card_word_size: |
1189 "card (UNIV :: 'a :: len word set) = (2 ^ size (x :: 'a word))" |
1189 "card (UNIV :: 'a :: finite word set) = (2 ^ size (x :: 'a word))" |
1190 unfolding word_size by (rule card_word) |
1190 unfolding word_size by (rule card_word) |
1191 |
1191 |
1192 end |
1192 end |
1193 |
1193 |