4538 subsection \<open>Split and cat\<close> |
4535 subsection \<open>Split and cat\<close> |
4539 |
4536 |
4540 lemmas word_split_bin' = word_split_def |
4537 lemmas word_split_bin' = word_split_def |
4541 lemmas word_cat_bin' = word_cat_eq |
4538 lemmas word_cat_bin' = word_cat_eq |
4542 |
4539 |
4543 lemma word_rsplit_no: |
|
4544 "(word_rsplit (numeral bin :: 'b::len word) :: 'a word list) = |
|
4545 map word_of_int (bin_rsplit (LENGTH('a::len)) |
|
4546 (LENGTH('b), take_bit (LENGTH('b)) (numeral bin)))" |
|
4547 by (simp add: word_rsplit_def of_nat_take_bit) |
|
4548 |
|
4549 lemmas word_rsplit_no_cl [simp] = word_rsplit_no |
|
4550 [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]] |
|
4551 |
|
4552 lemma test_bit_cat [OF refl]: |
4540 lemma test_bit_cat [OF refl]: |
4553 "wc = word_cat a b \<Longrightarrow> wc !! n = (n < size wc \<and> |
4541 "wc = word_cat a b \<Longrightarrow> wc !! n = (n < size wc \<and> |
4554 (if n < size b then b !! n else a !! (n - size b)))" |
4542 (if n < size b then b !! n else a !! (n - size b)))" |
4555 apply (simp add: word_size not_less; transfer) |
4543 apply (simp add: word_size not_less; transfer) |
4556 apply (auto simp add: bit_concat_bit_iff bit_take_bit_iff) |
4544 apply (auto simp add: bit_concat_bit_iff bit_take_bit_iff) |
4657 apply (drule test_bit_split) |
4645 apply (drule test_bit_split) |
4658 apply safe |
4646 apply safe |
4659 apply (rule word_eqI, clarsimp simp: test_bit_cat word_size)+ |
4647 apply (rule word_eqI, clarsimp simp: test_bit_cat word_size)+ |
4660 done |
4648 done |
4661 |
4649 |
4662 text \<open> |
|
4663 This odd result arises from the fact that the statement of the |
|
4664 result implies that the decoded words are of the same type, |
|
4665 and therefore of the same length, as the original word.\<close> |
|
4666 |
|
4667 lemma word_rsplit_same: "word_rsplit w = [w]" |
|
4668 apply (simp add: word_rsplit_def bin_rsplit_all) |
|
4669 apply transfer |
|
4670 apply simp |
|
4671 done |
|
4672 |
|
4673 lemma word_rsplit_empty_iff_size: "word_rsplit w = [] \<longleftrightarrow> size w = 0" |
|
4674 by (simp add: word_rsplit_def bin_rsplit_def word_size bin_rsplit_aux_simp_alt Let_def |
|
4675 split: prod.split) |
|
4676 |
|
4677 lemma test_bit_rsplit: |
|
4678 "sw = word_rsplit w \<Longrightarrow> m < size (hd sw) \<Longrightarrow> |
|
4679 k < length sw \<Longrightarrow> (rev sw ! k) !! m = w !! (k * size (hd sw) + m)" |
|
4680 for sw :: "'a::len word list" |
|
4681 apply (unfold word_rsplit_def word_test_bit_def) |
|
4682 apply (rule trans) |
|
4683 apply (rule_tac f = "\<lambda>x. bin_nth x m" in arg_cong) |
|
4684 apply (rule nth_map [symmetric]) |
|
4685 apply simp |
|
4686 apply (rule bin_nth_rsplit) |
|
4687 apply simp_all |
|
4688 apply (simp add : word_size rev_map) |
|
4689 apply (rule trans) |
|
4690 defer |
|
4691 apply (rule map_ident [THEN fun_cong]) |
|
4692 apply (rule refl [THEN map_cong]) |
|
4693 apply simp |
|
4694 using bin_rsplit_size_sign take_bit_int_eq_self_iff by blast |
|
4695 |
|
4696 lemma horner_sum_uint_exp_Cons_eq: |
4650 lemma horner_sum_uint_exp_Cons_eq: |
4697 \<open>horner_sum uint (2 ^ LENGTH('a)) (w # ws) = |
4651 \<open>horner_sum uint (2 ^ LENGTH('a)) (w # ws) = |
4698 concat_bit LENGTH('a) (uint w) (horner_sum uint (2 ^ LENGTH('a)) ws)\<close> |
4652 concat_bit LENGTH('a) (uint w) (horner_sum uint (2 ^ LENGTH('a)) ws)\<close> |
4699 for ws :: \<open>'a::len word list\<close> |
4653 for ws :: \<open>'a::len word list\<close> |
4700 apply (simp add: concat_bit_eq push_bit_eq_mult) |
4654 apply (simp add: concat_bit_eq push_bit_eq_mult) |
4723 for wl :: "'a::len word list" |
4677 for wl :: "'a::len word list" |
4724 by (simp add: word_size word_rcat_def bin_rcat_def foldl_map rev_map bit_horner_sum_uint_exp_iff) |
4678 by (simp add: word_size word_rcat_def bin_rcat_def foldl_map rev_map bit_horner_sum_uint_exp_iff) |
4725 (simp add: test_bit_eq_bit) |
4679 (simp add: test_bit_eq_bit) |
4726 |
4680 |
4727 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong] |
4681 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong] |
4728 |
|
4729 lemma test_bit_rsplit_alt: |
|
4730 \<open>(word_rsplit w :: 'b::len word list) ! i !! m \<longleftrightarrow> |
|
4731 w !! ((length (word_rsplit w :: 'b::len word list) - Suc i) * size (hd (word_rsplit w :: 'b::len word list)) + m)\<close> |
|
4732 if \<open>i < length (word_rsplit w :: 'b::len word list)\<close> \<open>m < size (hd (word_rsplit w :: 'b::len word list))\<close> \<open>0 < length (word_rsplit w :: 'b::len word list)\<close> |
|
4733 for w :: \<open>'a::len word\<close> |
|
4734 apply (rule trans) |
|
4735 apply (rule test_bit_cong) |
|
4736 apply (rule rev_nth [of _ \<open>rev (word_rsplit w)\<close>, simplified rev_rev_ident]) |
|
4737 apply simp |
|
4738 apply (rule that(1)) |
|
4739 apply simp |
|
4740 apply (rule test_bit_rsplit) |
|
4741 apply (rule refl) |
|
4742 apply (rule asm_rl) |
|
4743 apply (rule that(2)) |
|
4744 apply (rule diff_Suc_less) |
|
4745 apply (rule that(3)) |
|
4746 done |
|
4747 |
|
4748 lemma word_rsplit_len_indep [OF refl refl refl refl]: |
|
4749 "[u,v] = p \<Longrightarrow> [su,sv] = q \<Longrightarrow> word_rsplit u = su \<Longrightarrow> |
|
4750 word_rsplit v = sv \<Longrightarrow> length su = length sv" |
|
4751 by (auto simp: word_rsplit_def bin_rsplit_len_indep) |
|
4752 |
|
4753 lemma length_word_rsplit_size: |
|
4754 "n = LENGTH('a::len) \<Longrightarrow> |
|
4755 length (word_rsplit w :: 'a word list) \<le> m \<longleftrightarrow> size w \<le> m * n" |
|
4756 by (auto simp: word_rsplit_def word_size bin_rsplit_len_le) |
|
4757 |
|
4758 lemmas length_word_rsplit_lt_size = |
|
4759 length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]] |
|
4760 |
|
4761 lemma length_word_rsplit_exp_size: |
|
4762 "n = LENGTH('a::len) \<Longrightarrow> |
|
4763 length (word_rsplit w :: 'a word list) = (size w + n - 1) div n" |
|
4764 by (auto simp: word_rsplit_def word_size bin_rsplit_len) |
|
4765 |
|
4766 lemma length_word_rsplit_even_size: |
|
4767 "n = LENGTH('a::len) \<Longrightarrow> size w = m * n \<Longrightarrow> |
|
4768 length (word_rsplit w :: 'a word list) = m" |
|
4769 by (cases \<open>LENGTH('a)\<close>) (simp_all add: length_word_rsplit_exp_size div_nat_eqI) |
|
4770 |
|
4771 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size] |
|
4772 |
|
4773 \<comment> \<open>alternative proof of \<open>word_rcat_rsplit\<close>\<close> |
|
4774 lemmas tdle = times_div_less_eq_dividend |
|
4775 lemmas dtle = xtrans(4) [OF tdle mult.commute] |
|
4776 |
|
4777 lemma word_rcat_rsplit: "word_rcat (word_rsplit w) = w" |
|
4778 apply (rule word_eqI) |
|
4779 apply (clarsimp simp: test_bit_rcat word_size) |
|
4780 apply (subst refl [THEN test_bit_rsplit]) |
|
4781 apply (simp_all add: word_size |
|
4782 refl [THEN length_word_rsplit_size [simplified not_less [symmetric], simplified]]) |
|
4783 apply safe |
|
4784 apply (erule xtrans(7), rule dtle)+ |
|
4785 done |
|
4786 |
|
4787 lemma size_word_rsplit_rcat_size: |
|
4788 "word_rcat ws = frcw \<Longrightarrow> size frcw = length ws * LENGTH('a) |
|
4789 \<Longrightarrow> length (word_rsplit frcw::'a word list) = length ws" |
|
4790 for ws :: "'a::len word list" and frcw :: "'b::len word" |
|
4791 by (cases \<open>LENGTH('a)\<close>) (simp_all add: word_size length_word_rsplit_exp_size' div_nat_eqI) |
|
4792 |
|
4793 lemma msrevs: |
|
4794 "0 < n \<Longrightarrow> (k * n + m) div n = m div n + k" |
|
4795 "(k * n + m) mod n = m mod n" |
|
4796 for n :: nat |
|
4797 by (auto simp: add.commute) |
|
4798 |
|
4799 lemma word_rsplit_rcat_size [OF refl]: |
|
4800 "word_rcat ws = frcw \<Longrightarrow> |
|
4801 size frcw = length ws * LENGTH('a) \<Longrightarrow> word_rsplit frcw = ws" |
|
4802 for ws :: "'a::len word list" |
|
4803 apply (frule size_word_rsplit_rcat_size, assumption) |
|
4804 apply (clarsimp simp add : word_size) |
|
4805 apply (rule nth_equalityI, assumption) |
|
4806 apply clarsimp |
|
4807 apply (rule word_eqI [rule_format]) |
|
4808 apply (rule trans) |
|
4809 apply (rule test_bit_rsplit_alt) |
|
4810 apply (clarsimp simp: word_size)+ |
|
4811 apply (rule trans) |
|
4812 apply (rule test_bit_rcat [OF refl refl]) |
|
4813 apply (simp add: word_size) |
|
4814 apply (subst rev_nth) |
|
4815 apply arith |
|
4816 apply (simp add: le0 [THEN [2] xtrans(7), THEN diff_Suc_less]) |
|
4817 apply safe |
|
4818 apply (simp add: diff_mult_distrib) |
|
4819 apply (cases "size ws") |
|
4820 apply simp_all |
|
4821 done |
|
4822 |
4682 |
4823 |
4683 |
4824 subsection \<open>Rotation\<close> |
4684 subsection \<open>Rotation\<close> |
4825 |
4685 |
4826 lemma word_rotr_word_rotr_eq: |
4686 lemma word_rotr_word_rotr_eq: |