src/HOL/Word/Word.thy
changeset 72487 ab32922f139b
parent 72397 48013583e8e6
child 72488 ee659bca8955
equal deleted inserted replaced
72486:e4d707eb7d1b 72487:ab32922f139b
  2281   apply (simp add: word_rcat_def bin_rcat_def rev_map)
  2281   apply (simp add: word_rcat_def bin_rcat_def rev_map)
  2282   apply transfer
  2282   apply transfer
  2283   apply (simp add: horner_sum_foldr foldr_map comp_def)
  2283   apply (simp add: horner_sum_foldr foldr_map comp_def)
  2284   done
  2284   done
  2285 
  2285 
  2286 definition word_rsplit :: "'a::len word \<Rightarrow> 'b::len word list"
       
  2287   where "word_rsplit w = map word_of_int (bin_rsplit (LENGTH('b)) (LENGTH('a), uint w))"
       
  2288 
       
  2289 abbreviation (input) max_word :: \<open>'a::len word\<close>
  2286 abbreviation (input) max_word :: \<open>'a::len word\<close>
  2290   \<comment> \<open>Largest representable machine integer.\<close>
  2287   \<comment> \<open>Largest representable machine integer.\<close>
  2291   where "max_word \<equiv> - 1"
  2288   where "max_word \<equiv> - 1"
  2292 
  2289 
  2293 
  2290 
  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: