more consequent transferability
authorhaftmann
Sat Aug 01 17:43:30 2020 +0000 (7 weeks ago ago)
changeset 723118c355e2dd7db
parent 72308 b8d0b8659e0a
child 72312 b6065cbbf5e2
child 72313 2030eacf3a72
more consequent transferability
NEWS
src/HOL/Library/Bit_Operations.thy
src/HOL/Parity.thy
src/HOL/Word/Bit_Lists.thy
src/HOL/Word/Misc_lsb.thy
src/HOL/Word/More_Word.thy
src/HOL/Word/Word.thy
src/HOL/Word/Word_Examples.thy
src/HOL/ex/Word.thy
     1.1 --- a/NEWS	Wed Jul 29 14:23:19 2020 +0200
     1.2 +++ b/NEWS	Sat Aug 01 17:43:30 2020 +0000
     1.3 @@ -67,6 +67,9 @@
     1.4  generic algebraic bit operations from HOL-Library.Bit_Operations.
     1.5  INCOMPATIBILITY.
     1.6  
     1.7 +* Session HOL-Word: Most operations on type word are set up
     1.8 +for transfer and lifting.  INCOMPATIBILITY.
     1.9 +
    1.10  * Session HOL-Word: Theory "Word_Bitwise" has been moved to AFP entry
    1.11  Word_Lib as theory "Bitwise".  INCOMPATIBILITY.
    1.12  
     2.1 --- a/src/HOL/Library/Bit_Operations.thy	Wed Jul 29 14:23:19 2020 +0200
     2.2 +++ b/src/HOL/Library/Bit_Operations.thy	Sat Aug 01 17:43:30 2020 +0000
     2.3 @@ -236,9 +236,13 @@
     2.4    apply (use local.exp_eq_0_imp_not_bit in blast)
     2.5    done
     2.6  
     2.7 +lemma mask_eq_take_bit_minus_one:
     2.8 +  \<open>mask n = take_bit n (- 1)\<close>
     2.9 +  by (simp add: bit_eq_iff bit_mask_iff bit_take_bit_iff conj_commute)
    2.10 +
    2.11  lemma take_bit_minus_one_eq_mask:
    2.12    \<open>take_bit n (- 1) = mask n\<close>
    2.13 -  by (simp add: bit_eq_iff bit_mask_iff bit_take_bit_iff conj_commute)
    2.14 +  by (simp add: mask_eq_take_bit_minus_one)
    2.15  
    2.16  lemma minus_exp_eq_not_mask:
    2.17    \<open>- (2 ^ n) = NOT (mask n)\<close>
    2.18 @@ -252,6 +256,10 @@
    2.19    \<open>take_bit m (NOT (mask n)) = 0\<close> if \<open>n \<ge> m\<close>
    2.20    by (rule bit_eqI) (use that in \<open>simp add: bit_take_bit_iff bit_not_iff bit_mask_iff\<close>)
    2.21  
    2.22 +lemma take_bit_mask [simp]:
    2.23 +  \<open>take_bit m (mask n) = mask (min m n)\<close>
    2.24 +  by (simp add: mask_eq_take_bit_minus_one)
    2.25 +
    2.26  definition set_bit :: \<open>nat \<Rightarrow> 'a \<Rightarrow> 'a\<close>
    2.27    where \<open>set_bit n a = a OR push_bit n 1\<close>
    2.28  
    2.29 @@ -876,12 +884,9 @@
    2.30    by (rule bit_eqI) (auto simp add: bit_signed_take_bit_iff min_def bit_or_iff bit_not_iff bit_mask_iff bit_take_bit_iff)
    2.31  
    2.32  lemma take_bit_signed_take_bit:
    2.33 -  \<open>take_bit m (signed_take_bit n k) = take_bit m k\<close> if \<open>m \<le> n\<close>
    2.34 -  using that by (auto simp add: bit_eq_iff bit_take_bit_iff bit_signed_take_bit_iff min_def)
    2.35 -
    2.36 -lemma take_bit_Suc_signed_take_bit [simp]:
    2.37 -  \<open>take_bit (Suc n) (signed_take_bit n a) = take_bit (Suc n) a\<close>
    2.38 -  by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def less_Suc_eq)
    2.39 +  \<open>take_bit m (signed_take_bit n k) = take_bit m k\<close> if \<open>m \<le> Suc n\<close>
    2.40 +  using that by (rule le_SucE; intro bit_eqI)
    2.41 +   (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def less_Suc_eq)
    2.42  
    2.43  lemma signed_take_bit_take_bit:
    2.44    \<open>signed_take_bit m (take_bit n k) = (if n \<le> m then take_bit n else signed_take_bit m) k\<close>
     3.1 --- a/src/HOL/Parity.thy	Wed Jul 29 14:23:19 2020 +0200
     3.2 +++ b/src/HOL/Parity.thy	Sat Aug 01 17:43:30 2020 +0000
     3.3 @@ -1423,6 +1423,17 @@
     3.4      by (simp add: take_bit_push_bit)
     3.5  qed
     3.6  
     3.7 +lemma take_bit_tightened:
     3.8 +  \<open>take_bit m a = take_bit m b\<close> if \<open>take_bit n a = take_bit n b\<close> and \<open>m \<le> n\<close> 
     3.9 +proof -
    3.10 +  from that have \<open>take_bit m (take_bit n a) = take_bit m (take_bit n b)\<close>
    3.11 +    by simp
    3.12 +  then have \<open>take_bit (min m n) a = take_bit (min m n) b\<close>
    3.13 +    by simp
    3.14 +  with that show ?thesis
    3.15 +    by (simp add: min_def)
    3.16 +qed
    3.17 +
    3.18  end
    3.19  
    3.20  instantiation nat :: semiring_bit_shifts
    3.21 @@ -1666,6 +1677,11 @@
    3.22      for k :: int
    3.23    by (simp add: take_bit_eq_mod)
    3.24  
    3.25 +lemma not_take_bit_negative [simp]:
    3.26 +  \<open>\<not> take_bit n k < 0\<close>
    3.27 +    for k :: int
    3.28 +  by (simp add: not_less)
    3.29 +
    3.30  lemma take_bit_int_less_exp:
    3.31    \<open>take_bit n k < 2 ^ n\<close> for k :: int
    3.32    by (simp add: take_bit_eq_mod)
     4.1 --- a/src/HOL/Word/Bit_Lists.thy	Wed Jul 29 14:23:19 2020 +0200
     4.2 +++ b/src/HOL/Word/Bit_Lists.thy	Sat Aug 01 17:43:30 2020 +0000
     4.3 @@ -134,4 +134,166 @@
     4.4  lemma bl_bin_bl_rtf: "bin_to_bl n (bl_to_bin bl) = rev (takefill False n (rev bl))"
     4.5    by (simp add: takefill_bintrunc)
     4.6  
     4.7 +
     4.8 +subsection \<open>More\<close>
     4.9 +
    4.10 +definition rotater1 :: "'a list \<Rightarrow> 'a list"
    4.11 +  where "rotater1 ys =
    4.12 +    (case ys of [] \<Rightarrow> [] | x # xs \<Rightarrow> last ys # butlast ys)"
    4.13 +
    4.14 +definition rotater :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list"
    4.15 +  where "rotater n = rotater1 ^^ n"
    4.16 +
    4.17 +lemmas rotater_0' [simp] = rotater_def [where n = "0", simplified]
    4.18 +
    4.19 +lemma rotate1_rl': "rotater1 (l @ [a]) = a # l"
    4.20 +  by (cases l) (auto simp: rotater1_def)
    4.21 +
    4.22 +lemma rotate1_rl [simp] : "rotater1 (rotate1 l) = l"
    4.23 +  apply (unfold rotater1_def)
    4.24 +  apply (cases "l")
    4.25 +   apply (case_tac [2] "list")
    4.26 +    apply auto
    4.27 +  done
    4.28 +
    4.29 +lemma rotate1_lr [simp] : "rotate1 (rotater1 l) = l"
    4.30 +  by (cases l) (auto simp: rotater1_def)
    4.31 +
    4.32 +lemma rotater1_rev': "rotater1 (rev xs) = rev (rotate1 xs)"
    4.33 +  by (cases "xs") (simp add: rotater1_def, simp add: rotate1_rl')
    4.34 +
    4.35 +lemma rotater_rev': "rotater n (rev xs) = rev (rotate n xs)"
    4.36 +  by (induct n) (auto simp: rotater_def intro: rotater1_rev')
    4.37 +
    4.38 +lemma rotater_rev: "rotater n ys = rev (rotate n (rev ys))"
    4.39 +  using rotater_rev' [where xs = "rev ys"] by simp
    4.40 +
    4.41 +lemma rotater_drop_take:
    4.42 +  "rotater n xs =
    4.43 +    drop (length xs - n mod length xs) xs @
    4.44 +    take (length xs - n mod length xs) xs"
    4.45 +  by (auto simp: rotater_rev rotate_drop_take rev_take rev_drop)
    4.46 +
    4.47 +lemma rotater_Suc [simp]: "rotater (Suc n) xs = rotater1 (rotater n xs)"
    4.48 +  unfolding rotater_def by auto
    4.49 +
    4.50 +lemma nth_rotater:
    4.51 +  \<open>rotater m xs ! n = xs ! ((n + (length xs - m mod length xs)) mod length xs)\<close> if \<open>n < length xs\<close>
    4.52 +  using that by (simp add: rotater_drop_take nth_append not_less less_diff_conv ac_simps le_mod_geq)
    4.53 +
    4.54 +lemma nth_rotater1:
    4.55 +  \<open>rotater1 xs ! n = xs ! ((n + (length xs - 1)) mod length xs)\<close> if \<open>n < length xs\<close>
    4.56 +  using that nth_rotater [of n xs 1] by simp
    4.57 +
    4.58 +lemma rotate_inv_plus [rule_format]:
    4.59 +  "\<forall>k. k = m + n \<longrightarrow> rotater k (rotate n xs) = rotater m xs \<and>
    4.60 +    rotate k (rotater n xs) = rotate m xs \<and>
    4.61 +    rotater n (rotate k xs) = rotate m xs \<and>
    4.62 +    rotate n (rotater k xs) = rotater m xs"
    4.63 +  by (induct n) (auto simp: rotater_def rotate_def intro: funpow_swap1 [THEN trans])
    4.64 +
    4.65 +lemmas rotate_inv_rel = le_add_diff_inverse2 [symmetric, THEN rotate_inv_plus]
    4.66 +
    4.67 +lemmas rotate_inv_eq = order_refl [THEN rotate_inv_rel, simplified]
    4.68 +
    4.69 +lemmas rotate_lr [simp] = rotate_inv_eq [THEN conjunct1]
    4.70 +lemmas rotate_rl [simp] = rotate_inv_eq [THEN conjunct2, THEN conjunct1]
    4.71 +
    4.72 +lemma rotate_gal: "rotater n xs = ys \<longleftrightarrow> rotate n ys = xs"
    4.73 +  by auto
    4.74 +
    4.75 +lemma rotate_gal': "ys = rotater n xs \<longleftrightarrow> xs = rotate n ys"
    4.76 +  by auto
    4.77 +
    4.78 +lemma length_rotater [simp]: "length (rotater n xs) = length xs"
    4.79 +  by (simp add : rotater_rev)
    4.80 +
    4.81 +lemma rotate_eq_mod: "m mod length xs = n mod length xs \<Longrightarrow> rotate m xs = rotate n xs"
    4.82 +  apply (rule box_equals)
    4.83 +    defer
    4.84 +    apply (rule rotate_conv_mod [symmetric])+
    4.85 +  apply simp
    4.86 +  done
    4.87 +
    4.88 +lemma restrict_to_left: "x = y \<Longrightarrow> x = z \<longleftrightarrow> y = z"
    4.89 +  by simp
    4.90 +
    4.91 +lemmas rotate_eqs =
    4.92 +  trans [OF rotate0 [THEN fun_cong] id_apply]
    4.93 +  rotate_rotate [symmetric]
    4.94 +  rotate_id
    4.95 +  rotate_conv_mod
    4.96 +  rotate_eq_mod
    4.97 +
    4.98 +lemmas rrs0 = rotate_eqs [THEN restrict_to_left,
    4.99 +  simplified rotate_gal [symmetric] rotate_gal' [symmetric]]
   4.100 +lemmas rrs1 = rrs0 [THEN refl [THEN rev_iffD1]]
   4.101 +lemmas rotater_eqs = rrs1 [simplified length_rotater]
   4.102 +lemmas rotater_0 = rotater_eqs (1)
   4.103 +lemmas rotater_add = rotater_eqs (2)
   4.104 +
   4.105 +lemma butlast_map: "xs \<noteq> [] \<Longrightarrow> butlast (map f xs) = map f (butlast xs)"
   4.106 +  by (induct xs) auto
   4.107 +
   4.108 +lemma rotater1_map: "rotater1 (map f xs) = map f (rotater1 xs)"
   4.109 +  by (cases xs) (auto simp: rotater1_def last_map butlast_map)
   4.110 +
   4.111 +lemma rotater_map: "rotater n (map f xs) = map f (rotater n xs)"
   4.112 +  by (induct n) (auto simp: rotater_def rotater1_map)
   4.113 +
   4.114 +lemma but_last_zip [rule_format] :
   4.115 +  "\<forall>ys. length xs = length ys \<longrightarrow> xs \<noteq> [] \<longrightarrow>
   4.116 +    last (zip xs ys) = (last xs, last ys) \<and>
   4.117 +    butlast (zip xs ys) = zip (butlast xs) (butlast ys)"
   4.118 +  apply (induct xs)
   4.119 +   apply auto
   4.120 +     apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
   4.121 +  done
   4.122 +
   4.123 +lemma but_last_map2 [rule_format] :
   4.124 +  "\<forall>ys. length xs = length ys \<longrightarrow> xs \<noteq> [] \<longrightarrow>
   4.125 +    last (map2 f xs ys) = f (last xs) (last ys) \<and>
   4.126 +    butlast (map2 f xs ys) = map2 f (butlast xs) (butlast ys)"
   4.127 +  apply (induct xs)
   4.128 +   apply auto
   4.129 +     apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
   4.130 +  done
   4.131 +
   4.132 +lemma rotater1_zip:
   4.133 +  "length xs = length ys \<Longrightarrow>
   4.134 +    rotater1 (zip xs ys) = zip (rotater1 xs) (rotater1 ys)"
   4.135 +  apply (unfold rotater1_def)
   4.136 +  apply (cases xs)
   4.137 +   apply auto
   4.138 +   apply ((case_tac ys, auto simp: neq_Nil_conv but_last_zip)[1])+
   4.139 +  done
   4.140 +
   4.141 +lemma rotater1_map2:
   4.142 +  "length xs = length ys \<Longrightarrow>
   4.143 +    rotater1 (map2 f xs ys) = map2 f (rotater1 xs) (rotater1 ys)"
   4.144 +  by (simp add: rotater1_map rotater1_zip)
   4.145 +
   4.146 +lemmas lrth =
   4.147 +  box_equals [OF asm_rl length_rotater [symmetric]
   4.148 +                 length_rotater [symmetric],
   4.149 +              THEN rotater1_map2]
   4.150 +
   4.151 +lemma rotater_map2:
   4.152 +  "length xs = length ys \<Longrightarrow>
   4.153 +    rotater n (map2 f xs ys) = map2 f (rotater n xs) (rotater n ys)"
   4.154 +  by (induct n) (auto intro!: lrth)
   4.155 +
   4.156 +lemma rotate1_map2:
   4.157 +  "length xs = length ys \<Longrightarrow>
   4.158 +    rotate1 (map2 f xs ys) = map2 f (rotate1 xs) (rotate1 ys)"
   4.159 +  by (cases xs; cases ys) auto
   4.160 +
   4.161 +lemmas lth = box_equals [OF asm_rl length_rotate [symmetric]
   4.162 +  length_rotate [symmetric], THEN rotate1_map2]
   4.163 +
   4.164 +lemma rotate_map2:
   4.165 +  "length xs = length ys \<Longrightarrow>
   4.166 +    rotate n (map2 f xs ys) = map2 f (rotate n xs) (rotate n ys)"
   4.167 +  by (induct n) (auto intro!: lth)
   4.168 +
   4.169  end
     5.1 --- a/src/HOL/Word/Misc_lsb.thy	Wed Jul 29 14:23:19 2020 +0200
     5.2 +++ b/src/HOL/Word/Misc_lsb.thy	Sat Aug 01 17:43:30 2020 +0000
     5.3 @@ -60,7 +60,7 @@
     5.4    by (auto simp: word_test_bit_def word_lsb_def)
     5.5  
     5.6  lemma word_lsb_1_0 [simp]: "lsb (1::'a::len word) \<and> \<not> lsb (0::'b::len word)"
     5.7 -  unfolding word_lsb_def uint_eq_0 uint_1 by simp
     5.8 +  unfolding word_lsb_def by simp
     5.9  
    5.10  lemma word_lsb_last:
    5.11    \<open>lsb w \<longleftrightarrow> last (to_bl w)\<close>
     6.1 --- a/src/HOL/Word/More_Word.thy	Wed Jul 29 14:23:19 2020 +0200
     6.2 +++ b/src/HOL/Word/More_Word.thy	Sat Aug 01 17:43:30 2020 +0000
     6.3 @@ -1,4 +1,4 @@
     6.4 -(*  Title:      HOL/Word/More_Word.thy
     6.5 +(*  Title:      HOL/Word/More_thy
     6.6  *)
     6.7  
     6.8  section \<open>Ancient comprehensive Word Library\<close>
     6.9 @@ -15,4 +15,29 @@
    6.10  
    6.11  declare signed_take_bit_Suc [simp]
    6.12  
    6.13 +lemmas bshiftr1_def = bshiftr1_eq
    6.14 +lemmas is_down_def = is_down_eq
    6.15 +lemmas is_up_def = is_up_eq
    6.16 +lemmas mask_def = mask_eq_decr_exp
    6.17 +lemmas scast_def = scast_eq
    6.18 +lemmas shiftl1_def = shiftl1_eq
    6.19 +lemmas shiftr1_def = shiftr1_eq
    6.20 +lemmas sshiftr1_def = sshiftr1_eq
    6.21 +lemmas sshiftr_def = sshiftr_eq
    6.22 +lemmas to_bl_def = to_bl_eq
    6.23 +lemmas ucast_def = ucast_eq
    6.24 +lemmas unat_def = unat_eq_nat_uint
    6.25 +lemmas word_cat_def = word_cat_eq
    6.26 +lemmas word_reverse_def = word_reverse_eq_of_bl_rev_to_bl
    6.27 +lemmas word_roti_def = word_roti_eq_word_rotr_word_rotl
    6.28 +lemmas word_rotl_def = word_rotl_eq
    6.29 +lemmas word_rotr_def = word_rotr_eq
    6.30 +lemmas word_sle_def = word_sle_eq
    6.31 +lemmas word_sless_def = word_sless_eq
    6.32 +
    6.33 +lemma shiftl_transfer [transfer_rule]:
    6.34 +  includes lifting_syntax
    6.35 +  shows "(pcr_word ===> (=) ===> pcr_word) (<<) (<<)"
    6.36 +  by (auto intro!: rel_funI word_eqI simp add: word.pcr_cr_eq cr_word_def word_size nth_shiftl)
    6.37 +
    6.38  end
     7.1 --- a/src/HOL/Word/Word.thy	Wed Jul 29 14:23:19 2020 +0200
     7.2 +++ b/src/HOL/Word/Word.thy	Sat Aug 01 17:43:30 2020 +0000
     7.3 @@ -57,29 +57,64 @@
     7.4  
     7.5  subsection \<open>Type conversions and casting\<close>
     7.6  
     7.7 -definition sint :: "'a::len word \<Rightarrow> int"
     7.8 -  \<comment> \<open>treats the most-significant-bit as a sign bit\<close>
     7.9 -  where sint_uint: "sint w = sbintrunc (LENGTH('a) - 1) (uint w)"
    7.10 -
    7.11 -definition unat :: "'a::len word \<Rightarrow> nat"
    7.12 -  where "unat w = nat (uint w)"
    7.13 -
    7.14 -definition scast :: "'a::len word \<Rightarrow> 'b::len word"
    7.15 -  \<comment> \<open>cast a word to a different length\<close>
    7.16 -  where "scast w = word_of_int (sint w)"
    7.17 -
    7.18 -definition ucast :: "'a::len word \<Rightarrow> 'b::len word"
    7.19 -  where "ucast w = word_of_int (uint w)"
    7.20 +lemma signed_take_bit_decr_length_iff:
    7.21 +  \<open>signed_take_bit (LENGTH('a::len) - Suc 0) k = signed_take_bit (LENGTH('a) - Suc 0) l
    7.22 +    \<longleftrightarrow> take_bit LENGTH('a) k = take_bit LENGTH('a) l\<close>
    7.23 +  by (cases \<open>LENGTH('a)\<close>)
    7.24 +    (simp_all add: signed_take_bit_eq_iff_take_bit_eq)
    7.25 +
    7.26 +lift_definition sint :: \<open>'a::len word \<Rightarrow> int\<close>
    7.27 +  \<comment> \<open>treats the most-significant bit as a sign bit\<close>
    7.28 +  is \<open>signed_take_bit (LENGTH('a) - 1)\<close>  
    7.29 +  by (simp add: signed_take_bit_decr_length_iff)
    7.30 +
    7.31 +lemma sint_uint [code]:
    7.32 +  \<open>sint w = signed_take_bit (LENGTH('a) - 1) (uint w)\<close>
    7.33 +  for w :: \<open>'a::len word\<close>
    7.34 +  by transfer simp
    7.35 +
    7.36 +lift_definition unat :: \<open>'a::len word \<Rightarrow> nat\<close>
    7.37 +  is \<open>nat \<circ> take_bit LENGTH('a)\<close>
    7.38 +  by transfer simp
    7.39 +
    7.40 +lemma nat_uint_eq [simp]:
    7.41 +  \<open>nat (uint w) = unat w\<close>
    7.42 +  by transfer simp
    7.43 +
    7.44 +lemma unat_eq_nat_uint [code]:
    7.45 +  \<open>unat w = nat (uint w)\<close>
    7.46 +  by simp
    7.47 +
    7.48 +lift_definition ucast :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
    7.49 +  is \<open>take_bit LENGTH('a)\<close>
    7.50 +  by simp
    7.51 +
    7.52 +lemma ucast_eq [code]:
    7.53 +  \<open>ucast w = word_of_int (uint w)\<close>
    7.54 +  by transfer simp
    7.55 +
    7.56 +lift_definition scast :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
    7.57 +  is \<open>signed_take_bit (LENGTH('a) - 1)\<close>
    7.58 +  by (simp flip: signed_take_bit_decr_length_iff)
    7.59 +
    7.60 +lemma scast_eq [code]:
    7.61 +  \<open>scast w = word_of_int (sint w)\<close>
    7.62 +  by transfer simp
    7.63  
    7.64  instantiation word :: (len) size
    7.65  begin
    7.66  
    7.67 -definition word_size: "size (w :: 'a word) = LENGTH('a)"
    7.68 +lift_definition size_word :: \<open>'a word \<Rightarrow> nat\<close>
    7.69 +  is \<open>\<lambda>_. LENGTH('a)\<close> ..
    7.70  
    7.71  instance ..
    7.72  
    7.73  end
    7.74  
    7.75 +lemma word_size [code]:
    7.76 +  \<open>size w = LENGTH('a)\<close> for w :: \<open>'a::len word\<close>
    7.77 +  by (fact size_word.rep_eq)
    7.78 +
    7.79  lemma word_size_gt_0 [iff]: "0 < size w"
    7.80    for w :: "'a::len word"
    7.81    by (simp add: word_size)
    7.82 @@ -90,27 +125,46 @@
    7.83    \<open>size w \<noteq> 0\<close> for  w :: \<open>'a::len word\<close>
    7.84    by auto
    7.85  
    7.86 -definition source_size :: "('a::len word \<Rightarrow> 'b) \<Rightarrow> nat"
    7.87 -  \<comment> \<open>whether a cast (or other) function is to a longer or shorter length\<close>
    7.88 -  where [code del]: "source_size c = (let arb = undefined; x = c arb in size arb)"
    7.89 -
    7.90 -definition target_size :: "('a \<Rightarrow> 'b::len word) \<Rightarrow> nat"
    7.91 -  where [code del]: "target_size c = size (c undefined)"
    7.92 -
    7.93 -definition is_up :: "('a::len word \<Rightarrow> 'b::len word) \<Rightarrow> bool"
    7.94 -  where "is_up c \<longleftrightarrow> source_size c \<le> target_size c"
    7.95 -
    7.96 -definition is_down :: "('a::len word \<Rightarrow> 'b::len word) \<Rightarrow> bool"
    7.97 -  where "is_down c \<longleftrightarrow> target_size c \<le> source_size c"
    7.98 -
    7.99 -definition of_bl :: "bool list \<Rightarrow> 'a::len word"
   7.100 -  where "of_bl bl = word_of_int (bl_to_bin bl)"
   7.101 -
   7.102 -definition to_bl :: "'a::len word \<Rightarrow> bool list"
   7.103 -  where "to_bl w = bin_to_bl (LENGTH('a)) (uint w)"
   7.104 -
   7.105 -definition word_int_case :: "(int \<Rightarrow> 'b) \<Rightarrow> 'a::len word \<Rightarrow> 'b"
   7.106 -  where "word_int_case f w = f (uint w)"
   7.107 +lift_definition source_size :: \<open>('a::len word \<Rightarrow> 'b) \<Rightarrow> nat\<close>
   7.108 +  is \<open>\<lambda>_. LENGTH('a)\<close> .
   7.109 +
   7.110 +lift_definition target_size :: \<open>('a \<Rightarrow> 'b::len word) \<Rightarrow> nat\<close>
   7.111 +  is \<open>\<lambda>_. LENGTH('b)\<close> ..
   7.112 +
   7.113 +lift_definition is_up :: \<open>('a::len word \<Rightarrow> 'b::len word) \<Rightarrow> bool\<close>
   7.114 +  is \<open>\<lambda>_. LENGTH('a) \<le> LENGTH('b)\<close> ..
   7.115 +
   7.116 +lift_definition is_down :: \<open>('a::len word \<Rightarrow> 'b::len word) \<Rightarrow> bool\<close>
   7.117 +  is \<open>\<lambda>_. LENGTH('a) \<ge> LENGTH('b)\<close> ..
   7.118 +
   7.119 +lemma is_up_eq:
   7.120 +  \<open>is_up f \<longleftrightarrow> source_size f \<le> target_size f\<close>
   7.121 +  for f :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
   7.122 +  by (simp add: source_size.rep_eq target_size.rep_eq is_up.rep_eq)
   7.123 +
   7.124 +lemma is_down_eq:
   7.125 +  \<open>is_down f \<longleftrightarrow> target_size f \<le> source_size f\<close>
   7.126 +  for f :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
   7.127 +  by (simp add: source_size.rep_eq target_size.rep_eq is_down.rep_eq)
   7.128 +
   7.129 +lift_definition of_bl :: \<open>bool list \<Rightarrow> 'a::len word\<close>
   7.130 +  is bl_to_bin .
   7.131 +
   7.132 +lift_definition to_bl :: \<open>'a::len word \<Rightarrow> bool list\<close>
   7.133 +  is \<open>bin_to_bl LENGTH('a)\<close>
   7.134 +  by (simp add: bl_to_bin_inj)
   7.135 +
   7.136 +lemma to_bl_eq:
   7.137 +  \<open>to_bl w = bin_to_bl (LENGTH('a)) (uint w)\<close>
   7.138 +  for w :: \<open>'a::len word\<close>
   7.139 +  by transfer simp
   7.140 +
   7.141 +lift_definition word_int_case :: \<open>(int \<Rightarrow> 'b) \<Rightarrow> 'a::len word \<Rightarrow> 'b\<close>
   7.142 +  is \<open>\<lambda>f. f \<circ> take_bit LENGTH('a)\<close> by simp
   7.143 +
   7.144 +lemma word_int_case_eq_uint [code]:
   7.145 +  \<open>word_int_case f w = f (uint w)\<close>
   7.146 +  by transfer simp
   7.147  
   7.148  translations
   7.149    "case x of XCONST of_int y \<Rightarrow> b" \<rightleftharpoons> "CONST word_int_case (\<lambda>y. b) x"
   7.150 @@ -119,25 +173,37 @@
   7.151  
   7.152  subsection \<open>Basic code generation setup\<close>
   7.153  
   7.154 -definition Word :: "int \<Rightarrow> 'a::len word"
   7.155 -  where [code_post]: "Word = word_of_int"
   7.156 -
   7.157 -lemma [code abstype]: "Word (uint w) = w"
   7.158 -  by (simp add: Word_def word_of_int_uint)
   7.159 -
   7.160 -declare uint_word_of_int [code abstract]
   7.161 +lift_definition Word :: \<open>int \<Rightarrow> 'a::len word\<close>
   7.162 +  is id .
   7.163 +
   7.164 +lemma Word_eq_word_of_int [code_post]:
   7.165 +  \<open>Word = word_of_int\<close>
   7.166 +  by (simp add: fun_eq_iff Word.abs_eq)
   7.167 +
   7.168 +lemma [code abstype]:
   7.169 +  \<open>Word (uint w) = w\<close>
   7.170 +  by transfer simp
   7.171 +
   7.172 +lemma [code abstract]:
   7.173 +  \<open>uint (word_of_int k :: 'a::len word) = take_bit LENGTH('a) k\<close>
   7.174 +  by (fact uint.abs_eq)
   7.175  
   7.176  instantiation word :: (len) equal
   7.177  begin
   7.178  
   7.179 -definition equal_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> bool"
   7.180 -  where "equal_word k l \<longleftrightarrow> HOL.equal (uint k) (uint l)"
   7.181 +lift_definition equal_word :: \<open>'a word \<Rightarrow> 'a word \<Rightarrow> bool\<close>
   7.182 +  is \<open>\<lambda>k l. take_bit LENGTH('a) k = take_bit LENGTH('a) l\<close>
   7.183 +  by simp
   7.184  
   7.185  instance
   7.186 -  by standard (simp add: equal equal_word_def word_uint_eq_iff)
   7.187 +  by (standard; transfer) rule
   7.188  
   7.189  end
   7.190  
   7.191 +lemma [code]:
   7.192 +  \<open>HOL.equal k l \<longleftrightarrow> HOL.equal (uint k) (uint l)\<close>
   7.193 +  by transfer (simp add: equal)
   7.194 +
   7.195  notation fcomp (infixl "\<circ>>" 60)
   7.196  notation scomp (infixl "\<circ>\<rightarrow>" 60)
   7.197  
   7.198 @@ -263,6 +329,20 @@
   7.199  
   7.200  end
   7.201  
   7.202 +lemma uint_0_eq [simp, code]:
   7.203 +  \<open>uint 0 = 0\<close>
   7.204 +  by transfer simp
   7.205 +
   7.206 +quickcheck_generator word
   7.207 +  constructors:
   7.208 +    \<open>0 :: 'a::len word\<close>,
   7.209 +    \<open>numeral :: num \<Rightarrow> 'a::len word\<close>,
   7.210 +    \<open>uminus :: 'a word \<Rightarrow> 'a::len word\<close>
   7.211 +
   7.212 +lemma uint_1_eq [simp, code]:
   7.213 +  \<open>uint 1 = 1\<close>
   7.214 +  by transfer simp
   7.215 +
   7.216  lemma word_div_def [code]:
   7.217    "a div b = word_of_int (uint a div uint b)"
   7.218    by transfer rule
   7.219 @@ -271,12 +351,6 @@
   7.220    "a mod b = word_of_int (uint a mod uint b)"
   7.221    by transfer rule
   7.222  
   7.223 -quickcheck_generator word
   7.224 -  constructors:
   7.225 -    "zero_class.zero :: ('a::len) word",
   7.226 -    "numeral :: num \<Rightarrow> ('a::len) word",
   7.227 -    "uminus :: ('a::len) word \<Rightarrow> ('a::len) word"
   7.228 -
   7.229  context
   7.230    includes lifting_syntax
   7.231    notes power_transfer [transfer_rule]
   7.232 @@ -289,16 +363,15 @@
   7.233  end
   7.234  
   7.235  
   7.236 -
   7.237  text \<open>Legacy theorems:\<close>
   7.238  
   7.239 -lemma word_arith_wis [code]:
   7.240 -  shows word_add_def: "a + b = word_of_int (uint a + uint b)"
   7.241 -    and word_sub_wi: "a - b = word_of_int (uint a - uint b)"
   7.242 -    and word_mult_def: "a * b = word_of_int (uint a * uint b)"
   7.243 -    and word_minus_def: "- a = word_of_int (- uint a)"
   7.244 -    and word_succ_alt: "word_succ a = word_of_int (uint a + 1)"
   7.245 -    and word_pred_alt: "word_pred a = word_of_int (uint a - 1)"
   7.246 +lemma word_arith_wis:
   7.247 +  shows word_add_def [code]: "a + b = word_of_int (uint a + uint b)"
   7.248 +    and word_sub_wi [code]: "a - b = word_of_int (uint a - uint b)"
   7.249 +    and word_mult_def [code]: "a * b = word_of_int (uint a * uint b)"
   7.250 +    and word_minus_def [code]: "- a = word_of_int (- uint a)"
   7.251 +    and word_succ_alt [code]: "word_succ a = word_of_int (uint a + 1)"
   7.252 +    and word_pred_alt [code]: "word_pred a = word_of_int (uint a - 1)"
   7.253      and word_0_wi: "0 = word_of_int 0"
   7.254      and word_1_wi: "1 = word_of_int 1"
   7.255           apply (simp_all flip: plus_word.abs_eq minus_word.abs_eq
   7.256 @@ -539,11 +612,25 @@
   7.257    \<open>of_int k = (0 :: 'a::len word) \<longleftrightarrow> 2 ^ LENGTH('a) dvd k\<close>
   7.258    using of_int_word_eq_iff [where ?'a = 'a, of k 0] by (simp add: take_bit_eq_0_iff)
   7.259  
   7.260 -definition word_sle :: "'a::len word \<Rightarrow> 'a word \<Rightarrow> bool"  ("(_/ <=s _)" [50, 51] 50)
   7.261 -  where "a <=s b \<longleftrightarrow> sint a \<le> sint b"
   7.262 -
   7.263 -definition word_sless :: "'a::len word \<Rightarrow> 'a word \<Rightarrow> bool"  ("(_/ <s _)" [50, 51] 50)
   7.264 -  where "x <s y \<longleftrightarrow> x <=s y \<and> x \<noteq> y"
   7.265 +lift_definition word_sle :: \<open>'a::len word \<Rightarrow> 'a word \<Rightarrow> bool\<close>  (\<open>(_/ <=s _)\<close> [50, 51] 50)
   7.266 +  is \<open>\<lambda>k l. signed_take_bit (LENGTH('a) - 1) k \<le> signed_take_bit (LENGTH('a) - 1) l\<close>
   7.267 +  by (simp flip: signed_take_bit_decr_length_iff)
   7.268 +
   7.269 +lemma word_sle_eq [code]:
   7.270 +  \<open>a <=s b \<longleftrightarrow> sint a \<le> sint b\<close>
   7.271 +  by transfer simp
   7.272 +  
   7.273 +lift_definition word_sless :: \<open>'a::len word \<Rightarrow> 'a word \<Rightarrow> bool\<close>  (\<open>(_/ <s _)\<close> [50, 51] 50)
   7.274 +  is \<open>\<lambda>k l. signed_take_bit (LENGTH('a) - 1) k < signed_take_bit (LENGTH('a) - 1) l\<close>
   7.275 +  by (simp flip: signed_take_bit_decr_length_iff)
   7.276 +
   7.277 +lemma word_sless_eq:
   7.278 +  \<open>x <s y \<longleftrightarrow> x <=s y \<and> x \<noteq> y\<close>
   7.279 +  by transfer (simp add: signed_take_bit_decr_length_iff less_le)
   7.280 +
   7.281 +lemma [code]:
   7.282 +  \<open>a <s b \<longleftrightarrow> sint a < sint b\<close>
   7.283 +  by transfer simp
   7.284  
   7.285  
   7.286  subsection \<open>Bit-wise operations\<close>
   7.287 @@ -599,7 +686,7 @@
   7.288    moreover have \<open>of_nat (nat (uint a)) = a\<close>
   7.289      by transfer simp
   7.290    ultimately show ?thesis
   7.291 -    by (simp add: n_def unat_def)
   7.292 +    by (simp add: n_def)
   7.293  qed
   7.294  
   7.295  lemma bit_word_half_eq:
   7.296 @@ -828,6 +915,10 @@
   7.297    \<open>\<not> bit w LENGTH('a)\<close> for w :: \<open>'a::len word\<close>
   7.298    by transfer simp
   7.299  
   7.300 +lemma uint_take_bit_eq [code]:
   7.301 +  \<open>uint (take_bit n w) = take_bit n (uint w)\<close>
   7.302 +  by transfer (simp add: ac_simps)
   7.303 +
   7.304  lemma take_bit_length_eq [simp]:
   7.305    \<open>take_bit LENGTH('a) w = w\<close> for w :: \<open>'a::len word\<close>
   7.306    by transfer simp
   7.307 @@ -844,54 +935,51 @@
   7.308  lemma bit_sint_iff:
   7.309    \<open>bit (sint w) n \<longleftrightarrow> n \<ge> LENGTH('a) \<and> bit w (LENGTH('a) - 1) \<or> bit w n\<close>
   7.310    for w :: \<open>'a::len word\<close>
   7.311 -  apply (cases \<open>LENGTH('a)\<close>)
   7.312 -   apply simp
   7.313 -  apply (simp add: sint_uint nth_sbintr not_less bit_uint_iff not_le Suc_le_eq)
   7.314 -  apply (auto simp add: le_less dest: bit_imp_le_length)
   7.315 -  done
   7.316 +  by transfer (auto simp add: bit_signed_take_bit_iff min_def le_less not_less)
   7.317  
   7.318  lemma bit_word_ucast_iff:
   7.319    \<open>bit (ucast w :: 'b::len word) n \<longleftrightarrow> n < LENGTH('a) \<and> n < LENGTH('b) \<and> bit w n\<close>
   7.320    for w :: \<open>'a::len word\<close>
   7.321 -  by (simp add: ucast_def bit_word_of_int_iff bit_uint_iff ac_simps)
   7.322 +  by transfer (simp add: bit_take_bit_iff ac_simps)
   7.323  
   7.324  lemma bit_word_scast_iff:
   7.325    \<open>bit (scast w :: 'b::len word) n \<longleftrightarrow>
   7.326      n < LENGTH('b) \<and> (bit w n \<or> LENGTH('a) \<le> n \<and> bit w (LENGTH('a) - Suc 0))\<close>
   7.327    for w :: \<open>'a::len word\<close>
   7.328 -  by (simp add: scast_def bit_word_of_int_iff bit_sint_iff ac_simps)
   7.329 -
   7.330 -definition shiftl1 :: "'a::len word \<Rightarrow> 'a word"
   7.331 -  where "shiftl1 w = word_of_int (2 * uint w)"
   7.332 +  by transfer (auto simp add: bit_signed_take_bit_iff le_less min_def)
   7.333 +
   7.334 +lift_definition shiftl1 :: \<open>'a::len word \<Rightarrow> 'a word\<close>
   7.335 +  is \<open>(*) 2\<close>
   7.336 +  by (auto simp add: take_bit_eq_mod intro: mod_mult_cong)
   7.337 +
   7.338 +lemma shiftl1_eq:
   7.339 +  \<open>shiftl1 w = word_of_int (2 * uint w)\<close>
   7.340 +  by transfer (simp add: take_bit_eq_mod mod_simps)
   7.341  
   7.342  lemma shiftl1_eq_mult_2:
   7.343    \<open>shiftl1 = (*) 2\<close>
   7.344 -  apply (simp add: fun_eq_iff shiftl1_def)
   7.345 -  apply transfer
   7.346 -  apply (simp only: mult_2 take_bit_add)
   7.347 -  apply simp
   7.348 -  done
   7.349 +  by (rule ext, transfer) simp
   7.350  
   7.351  lemma bit_shiftl1_iff:
   7.352    \<open>bit (shiftl1 w) n \<longleftrightarrow> 0 < n \<and> n < LENGTH('a) \<and> bit w (n - 1)\<close>
   7.353      for w :: \<open>'a::len word\<close>
   7.354    by (simp add: shiftl1_eq_mult_2 bit_double_iff exp_eq_zero_iff not_le) (simp add: ac_simps)
   7.355  
   7.356 -definition shiftr1 :: "'a::len word \<Rightarrow> 'a word"
   7.357 +lift_definition shiftr1 :: \<open>'a::len word \<Rightarrow> 'a word\<close>
   7.358    \<comment> \<open>shift right as unsigned or as signed, ie logical or arithmetic\<close>
   7.359 -  where "shiftr1 w = word_of_int (bin_rest (uint w))"
   7.360 +  is \<open>\<lambda>k. take_bit LENGTH('a) k div 2\<close> by simp
   7.361  
   7.362  lemma shiftr1_eq_div_2:
   7.363    \<open>shiftr1 w = w div 2\<close>
   7.364 -  apply (simp add: fun_eq_iff shiftr1_def)
   7.365 -  apply transfer
   7.366 -  apply (auto simp add: not_le dest: less_2_cases)
   7.367 -  done
   7.368 +  by transfer simp
   7.369  
   7.370  lemma bit_shiftr1_iff:
   7.371    \<open>bit (shiftr1 w) n \<longleftrightarrow> bit w (Suc n)\<close>
   7.372 -    for w :: \<open>'a::len word\<close>
   7.373 -  by (simp add: shiftr1_eq_div_2 bit_Suc)
   7.374 +  by transfer (auto simp flip: bit_Suc simp add: bit_take_bit_iff)
   7.375 +
   7.376 +lemma shiftr1_eq:
   7.377 +  \<open>shiftr1 w = word_of_int (bin_rest (uint w))\<close>
   7.378 +  by transfer simp
   7.379  
   7.380  instantiation word :: (len) ring_bit_operations
   7.381  begin
   7.382 @@ -932,15 +1020,15 @@
   7.383    includes lifting_syntax
   7.384  begin
   7.385  
   7.386 -lemma set_bit_word_transfer:
   7.387 +lemma set_bit_word_transfer [transfer_rule]:
   7.388    \<open>((=) ===> pcr_word ===> pcr_word) set_bit set_bit\<close>
   7.389    by (unfold set_bit_def) transfer_prover
   7.390  
   7.391 -lemma unset_bit_word_transfer:
   7.392 +lemma unset_bit_word_transfer [transfer_rule]:
   7.393    \<open>((=) ===> pcr_word ===> pcr_word) unset_bit unset_bit\<close>
   7.394    by (unfold unset_bit_def) transfer_prover
   7.395  
   7.396 -lemma flip_bit_word_transfer:
   7.397 +lemma flip_bit_word_transfer [transfer_rule]:
   7.398    \<open>((=) ===> pcr_word ===> pcr_word) flip_bit flip_bit\<close>
   7.399    by (unfold flip_bit_def) transfer_prover
   7.400  
   7.401 @@ -949,32 +1037,120 @@
   7.402  instantiation word :: (len) semiring_bit_syntax
   7.403  begin
   7.404  
   7.405 -definition word_test_bit_def: "test_bit a = bin_nth (uint a)"
   7.406 -
   7.407 -definition shiftl_def: "w << n = (shiftl1 ^^ n) w"
   7.408 -
   7.409 -definition shiftr_def: "w >> n = (shiftr1 ^^ n) w"
   7.410 +lift_definition test_bit_word :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> bool\<close>
   7.411 +  is \<open>\<lambda>k n. n < LENGTH('a) \<and> bit k n\<close>
   7.412 +proof
   7.413 +  fix k l :: int and n :: nat
   7.414 +  assume *: \<open>take_bit LENGTH('a) k = take_bit LENGTH('a) l\<close>
   7.415 +  show \<open>n < LENGTH('a) \<and> bit k n \<longleftrightarrow> n < LENGTH('a) \<and> bit l n\<close>
   7.416 +  proof (cases \<open>n < LENGTH('a)\<close>)
   7.417 +    case True
   7.418 +    from * have \<open>bit (take_bit LENGTH('a) k) n \<longleftrightarrow> bit (take_bit LENGTH('a) l) n\<close>
   7.419 +      by simp
   7.420 +    then show ?thesis
   7.421 +      by (simp add: bit_take_bit_iff)
   7.422 +  next
   7.423 +    case False
   7.424 +    then show ?thesis
   7.425 +      by simp
   7.426 +  qed
   7.427 +qed
   7.428  
   7.429  lemma test_bit_word_eq:
   7.430 -  \<open>test_bit w = bit w\<close> for w :: \<open>'a::len word\<close>
   7.431 -  apply (simp add: word_test_bit_def fun_eq_iff)
   7.432 -  apply transfer
   7.433 -  apply (simp add: bit_take_bit_iff)
   7.434 +  \<open>test_bit = (bit :: 'a word \<Rightarrow> _)\<close>
   7.435 +  by transfer simp
   7.436 +
   7.437 +lemma [code]:
   7.438 +  \<open>bit w n \<longleftrightarrow> w AND push_bit n 1 \<noteq> 0\<close>
   7.439 +  for w :: \<open>'a::len word\<close>
   7.440 +  apply (simp add: bit_eq_iff)
   7.441 +  apply (auto simp add: bit_and_iff bit_push_bit_iff bit_1_iff exp_eq_0_imp_not_bit)
   7.442 +  done
   7.443 +
   7.444 +lemma [code]:
   7.445 +  \<open>test_bit w n \<longleftrightarrow> w AND push_bit n 1 \<noteq> 0\<close>
   7.446 +  for w :: \<open>'a::len word\<close>
   7.447 +  apply (simp add: test_bit_word_eq bit_eq_iff)
   7.448 +  apply (auto simp add: bit_and_iff bit_push_bit_iff bit_1_iff exp_eq_0_imp_not_bit)
   7.449    done
   7.450  
   7.451 +lift_definition shiftl_word :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> 'a word\<close>
   7.452 +  is \<open>\<lambda>k n. push_bit n k\<close>
   7.453 +proof -
   7.454 +  show \<open>take_bit LENGTH('a) (push_bit n k) = take_bit LENGTH('a) (push_bit n l)\<close>
   7.455 +    if \<open>take_bit LENGTH('a) k = take_bit LENGTH('a) l\<close> for k l :: int and n :: nat
   7.456 +  proof -
   7.457 +    from that
   7.458 +    have \<open>take_bit (LENGTH('a) - n) (take_bit LENGTH('a) k)
   7.459 +      = take_bit (LENGTH('a) - n) (take_bit LENGTH('a) l)\<close>
   7.460 +      by simp
   7.461 +    moreover have \<open>min (LENGTH('a) - n) LENGTH('a) = LENGTH('a) - n\<close>
   7.462 +      by simp
   7.463 +    ultimately show ?thesis
   7.464 +      by (simp add: take_bit_push_bit)
   7.465 +  qed
   7.466 +qed
   7.467 +
   7.468  lemma shiftl_word_eq:
   7.469    \<open>w << n = push_bit n w\<close> for w :: \<open>'a::len word\<close>
   7.470 -  by (induction n) (simp_all add: shiftl_def shiftl1_eq_mult_2 push_bit_double)
   7.471 -
   7.472 +  by transfer rule
   7.473 +
   7.474 +lift_definition shiftr_word :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> 'a word\<close>
   7.475 +  is \<open>\<lambda>k n. drop_bit n (take_bit LENGTH('a) k)\<close> by simp
   7.476 +  
   7.477  lemma shiftr_word_eq:
   7.478    \<open>w >> n = drop_bit n w\<close> for w :: \<open>'a::len word\<close>
   7.479 -  by (induction n) (simp_all add: shiftr_def shiftr1_eq_div_2 drop_bit_Suc drop_bit_half)
   7.480 -
   7.481 -instance by standard
   7.482 -  (simp_all add: fun_eq_iff test_bit_word_eq shiftl_word_eq shiftr_word_eq)
   7.483 +  by transfer simp
   7.484 +
   7.485 +instance
   7.486 +  by (standard; transfer) simp_all
   7.487  
   7.488  end
   7.489  
   7.490 +lemma shiftl_code [code]:
   7.491 +  \<open>w << n = w * 2 ^ n\<close>
   7.492 +  for w :: \<open>'a::len word\<close>
   7.493 +  by transfer (simp add: push_bit_eq_mult)
   7.494 +
   7.495 +lemma shiftl1_code [code]:
   7.496 +  \<open>shiftl1 w = w << 1\<close>
   7.497 +  by transfer (simp add: push_bit_eq_mult ac_simps)
   7.498 +
   7.499 +lemma uint_shiftr_eq [code]:
   7.500 +  \<open>uint (w >> n) = uint w div 2 ^ n\<close>
   7.501 +  for w :: \<open>'a::len word\<close>
   7.502 +  by transfer (simp flip: drop_bit_eq_div add: drop_bit_take_bit min_def le_less less_diff_conv)
   7.503 +
   7.504 +lemma shiftr1_code [code]:
   7.505 +  \<open>shiftr1 w = w >> 1\<close>
   7.506 +  by transfer (simp add: drop_bit_Suc)
   7.507 +
   7.508 +lemma word_test_bit_def: 
   7.509 +  \<open>test_bit a = bin_nth (uint a)\<close>
   7.510 +  by transfer (simp add: fun_eq_iff bit_take_bit_iff)
   7.511 +
   7.512 +lemma shiftl_def:
   7.513 +  \<open>w << n = (shiftl1 ^^ n) w\<close>
   7.514 +proof -
   7.515 +  have \<open>push_bit n = (((*) 2 ^^ n) :: int \<Rightarrow> int)\<close> for n
   7.516 +    by (induction n) (simp_all add: fun_eq_iff funpow_swap1, simp add: ac_simps)
   7.517 +  then show ?thesis
   7.518 +    by transfer simp
   7.519 +qed
   7.520 +
   7.521 +lemma shiftr_def:
   7.522 +  \<open>w >> n = (shiftr1 ^^ n) w\<close>
   7.523 +proof -
   7.524 +  have \<open>drop_bit n = (((\<lambda>k::int. k div 2) ^^ n))\<close> for n
   7.525 +    by (rule sym, induction n)
   7.526 +       (simp_all add: fun_eq_iff drop_bit_Suc flip: drop_bit_half)
   7.527 +  then show ?thesis
   7.528 +    apply transfer
   7.529 +    apply simp
   7.530 +    apply (metis bintrunc_bintrunc rco_bintr)
   7.531 +    done
   7.532 +qed
   7.533 +
   7.534  lemma bit_shiftl_word_iff:
   7.535    \<open>bit (w << m) n \<longleftrightarrow> m \<le> n \<and> n < LENGTH('a) \<and> bit w (n - m)\<close>
   7.536    for w :: \<open>'a::len word\<close>
   7.537 @@ -994,35 +1170,57 @@
   7.538    by (simp add: shiftr_word_eq)
   7.539  
   7.540  lemma [code]:
   7.541 -  \<open>take_bit n a = a AND Bit_Operations.mask n\<close> for a :: \<open>'a::len word\<close>
   7.542 +  \<open>take_bit n a = a AND mask n\<close> for a :: \<open>'a::len word\<close>
   7.543    by (fact take_bit_eq_mask)
   7.544  
   7.545  lemma [code_abbrev]:
   7.546    \<open>push_bit n 1 = (2 :: 'a::len word) ^ n\<close>
   7.547    by (fact push_bit_of_1)
   7.548  
   7.549 -lemma [code]:
   7.550 -  shows word_not_def: "NOT (a::'a::len word) = word_of_int (NOT (uint a))"
   7.551 +lemma
   7.552 +  word_not_def [code]: "NOT (a::'a::len word) = word_of_int (NOT (uint a))"
   7.553      and word_and_def: "(a::'a word) AND b = word_of_int (uint a AND uint b)"
   7.554      and word_or_def: "(a::'a word) OR b = word_of_int (uint a OR uint b)"
   7.555      and word_xor_def: "(a::'a word) XOR b = word_of_int (uint a XOR uint b)"
   7.556    by (transfer, simp add: take_bit_not_take_bit)+
   7.557  
   7.558 -definition setBit :: "'a::len word \<Rightarrow> nat \<Rightarrow> 'a word"
   7.559 -  where \<open>setBit w n = Bit_Operations.set_bit n w\<close>
   7.560 +lemma [code abstract]:
   7.561 +  \<open>uint (v AND w) = uint v AND uint w\<close>
   7.562 +  by transfer simp
   7.563 +
   7.564 +lemma [code abstract]:
   7.565 +  \<open>uint (v OR w) = uint v OR uint w\<close>
   7.566 +  by transfer simp
   7.567 +
   7.568 +lemma [code abstract]:
   7.569 +  \<open>uint (v XOR w) = uint v XOR uint w\<close>
   7.570 +  by transfer simp
   7.571 +
   7.572 +lift_definition setBit :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> 'a word\<close>
   7.573 +  is \<open>\<lambda>k n. set_bit n k\<close>
   7.574 +  by (simp add: take_bit_set_bit_eq)
   7.575 +
   7.576 +lemma set_Bit_eq:
   7.577 +  \<open>setBit w n = set_bit n w\<close>
   7.578 +  by transfer simp
   7.579  
   7.580  lemma bit_setBit_iff:
   7.581    \<open>bit (setBit w m) n \<longleftrightarrow> (m = n \<and> n < LENGTH('a) \<or> bit w n)\<close>
   7.582    for w :: \<open>'a::len word\<close>
   7.583 -  by (simp add: setBit_def bit_set_bit_iff exp_eq_zero_iff not_le ac_simps)
   7.584 -
   7.585 -definition clearBit :: "'a::len word \<Rightarrow> nat \<Rightarrow> 'a word"
   7.586 -  where \<open>clearBit w n = unset_bit n w\<close>
   7.587 +  by transfer (auto simp add: bit_set_bit_iff)
   7.588 +
   7.589 +lift_definition clearBit :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> 'a word\<close>
   7.590 +  is \<open>\<lambda>k n. unset_bit n k\<close>
   7.591 +  by (simp add: take_bit_unset_bit_eq)
   7.592 +
   7.593 +lemma clear_Bit_eq:
   7.594 +  \<open>clearBit w n = unset_bit n w\<close>
   7.595 +  by transfer simp
   7.596  
   7.597  lemma bit_clearBit_iff:
   7.598    \<open>bit (clearBit w m) n \<longleftrightarrow> m \<noteq> n \<and> bit w n\<close>
   7.599    for w :: \<open>'a::len word\<close>
   7.600 -  by (simp add: clearBit_def bit_unset_bit_iff ac_simps)
   7.601 +  by transfer (auto simp add: bit_unset_bit_iff)
   7.602  
   7.603  definition even_word :: \<open>'a::len word \<Rightarrow> bool\<close>
   7.604    where [code_abbrev]: \<open>even_word = even\<close>
   7.605 @@ -1035,58 +1233,305 @@
   7.606    \<open>bit a n \<longleftrightarrow> drop_bit n a AND 1 = 1\<close> for a :: \<open>'a::len word\<close>
   7.607    by (simp add: bit_iff_odd_drop_bit odd_iff_mod_2_eq_one and_one_eq)
   7.608  
   7.609 -
   7.610 -subsection \<open>Shift operations\<close>
   7.611 -
   7.612 -definition sshiftr1 :: "'a::len word \<Rightarrow> 'a word"
   7.613 -  where "sshiftr1 w = word_of_int (bin_rest (sint w))"
   7.614 -
   7.615 -definition bshiftr1 :: "bool \<Rightarrow> 'a::len word \<Rightarrow> 'a word"
   7.616 -  where "bshiftr1 b w = of_bl (b # butlast (to_bl w))"
   7.617 -
   7.618 -definition sshiftr :: "'a::len word \<Rightarrow> nat \<Rightarrow> 'a word"  (infixl ">>>" 55)
   7.619 -  where "w >>> n = (sshiftr1 ^^ n) w"
   7.620 -
   7.621 -definition mask :: "nat \<Rightarrow> 'a::len word"
   7.622 -  where "mask n = (1 << n) - 1"
   7.623 +lemma map_bit_range_eq_if_take_bit_eq:
   7.624 +  \<open>map (bit k) [0..<n] = map (bit l) [0..<n]\<close>
   7.625 +  if \<open>take_bit n k = take_bit n l\<close> for k l :: int
   7.626 +using that proof (induction n arbitrary: k l)
   7.627 +  case 0
   7.628 +  then show ?case
   7.629 +    by simp
   7.630 +next
   7.631 +  case (Suc n)
   7.632 +  from Suc.prems have \<open>take_bit n (k div 2) = take_bit n (l div 2)\<close>
   7.633 +    by (simp add: take_bit_Suc)
   7.634 +  then have \<open>map (bit (k div 2)) [0..<n] = map (bit (l div 2)) [0..<n]\<close>
   7.635 +    by (rule Suc.IH)
   7.636 +  moreover have \<open>bit (r div 2) = bit r \<circ> Suc\<close> for r :: int
   7.637 +    by (simp add: fun_eq_iff bit_Suc)
   7.638 +  moreover from Suc.prems have \<open>even k \<longleftrightarrow> even l\<close>
   7.639 +    by (auto simp add: take_bit_Suc elim!: evenE oddE) arith+
   7.640 +  ultimately show ?case
   7.641 +    by (simp only: map_Suc_upt upt_conv_Cons flip: list.map_comp) simp
   7.642 +qed
   7.643 +
   7.644 +lemma bit_of_bl_iff:
   7.645 +  \<open>bit (of_bl bs :: 'a word) n \<longleftrightarrow> rev bs ! n \<and> n < LENGTH('a::len) \<and> n < length bs\<close>
   7.646 +  by (auto simp add: of_bl_def bit_word_of_int_iff bin_nth_of_bl)
   7.647 +
   7.648 +lemma rev_to_bl_eq:
   7.649 +  \<open>rev (to_bl w) = map (bit w) [0..<LENGTH('a)]\<close>
   7.650 +  for w :: \<open>'a::len word\<close>
   7.651 +  apply (rule nth_equalityI)
   7.652 +   apply (simp add: to_bl.rep_eq)
   7.653 +  apply (simp add: bin_nth_bl bit_word.rep_eq to_bl.rep_eq)
   7.654 +  done
   7.655 +
   7.656 +lemma of_bl_rev_eq:
   7.657 +  \<open>of_bl (rev bs) = horner_sum of_bool 2 bs\<close>
   7.658 +  apply (rule bit_word_eqI)
   7.659 +  apply (simp add: bit_of_bl_iff)
   7.660 +  apply transfer
   7.661 +  apply (simp add: bit_horner_sum_bit_iff ac_simps)
   7.662 +  done
   7.663 +
   7.664 +
   7.665 +subsection \<open>More shift operations\<close>
   7.666 +
   7.667 +lift_definition sshiftr1 :: \<open>'a::len word \<Rightarrow> 'a word\<close>
   7.668 +  is \<open>\<lambda>k. take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - 1) k div 2)\<close>
   7.669 +  by (simp flip: signed_take_bit_decr_length_iff)
   7.670 + 
   7.671 +lift_definition sshiftr :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> 'a word\<close>  (infixl \<open>>>>\<close> 55)
   7.672 +  is \<open>\<lambda>k n. take_bit LENGTH('a) (drop_bit n (signed_take_bit (LENGTH('a) - 1) k))\<close>
   7.673 +  by (simp flip: signed_take_bit_decr_length_iff)
   7.674 +
   7.675 +lift_definition bshiftr1 :: \<open>bool \<Rightarrow> 'a::len word \<Rightarrow> 'a word\<close>
   7.676 +  is \<open>\<lambda>b k. take_bit LENGTH('a) k div 2 + of_bool b * 2 ^ (LENGTH('a) - Suc 0)\<close>
   7.677 +  by (fact arg_cong)
   7.678 +
   7.679 +lift_definition mask :: \<open>nat \<Rightarrow> 'a::len word\<close>
   7.680 +  is \<open>take_bit LENGTH('a) \<circ> Bit_Operations.mask\<close> .
   7.681 +
   7.682 +lemma sshiftr1_eq:
   7.683 +  \<open>sshiftr1 w = word_of_int (bin_rest (sint w))\<close>
   7.684 +  by transfer simp
   7.685 +
   7.686 +lemma bshiftr1_eq:
   7.687 +  \<open>bshiftr1 b w = of_bl (b # butlast (to_bl w))\<close>
   7.688 +  apply transfer
   7.689 +  apply auto
   7.690 +   apply (subst bl_to_bin_app_cat [of \<open>[True]\<close>, simplified])
   7.691 +   apply simp
   7.692 +   apply (metis One_nat_def add.commute bin_bl_bin bin_last_bl_to_bin bin_rest_bl_to_bin butlast_bin_rest concat_bit_eq last.simps list.distinct(1) list.size(3) list.size(4) odd_iff_mod_2_eq_one plus_1_eq_Suc power_Suc0_right push_bit_of_1 size_bin_to_bl take_bit_eq_mod trunc_bl2bin_len)
   7.693 +  apply (simp add: butlast_rest_bl2bin)
   7.694 +  done
   7.695 +
   7.696 +lemma sshiftr_eq:
   7.697 +  \<open>w >>> n = (sshiftr1 ^^ n) w\<close>
   7.698 +proof -
   7.699 +  have *: \<open>(\<lambda>k. take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - Suc 0) k div 2)) ^^ Suc n =
   7.700 +    take_bit LENGTH('a) \<circ> drop_bit (Suc n) \<circ> signed_take_bit (LENGTH('a) - Suc 0)\<close>
   7.701 +    for n
   7.702 +    apply (induction n)
   7.703 +     apply (auto simp add: fun_eq_iff drop_bit_Suc)
   7.704 +    apply (metis (no_types, lifting) Suc_pred funpow_swap1 len_gt_0 sbintrunc_bintrunc sbintrunc_rest)
   7.705 +    done
   7.706 +  show ?thesis
   7.707 +    apply transfer
   7.708 +    apply simp
   7.709 +    subgoal for k n
   7.710 +      apply (cases n)
   7.711 +       apply (simp_all only: *)
   7.712 +       apply simp_all
   7.713 +      done
   7.714 +    done
   7.715 +qed
   7.716 +
   7.717 +lemma mask_eq:
   7.718 +  \<open>mask n = (1 << n) - 1\<close>
   7.719 +  by transfer (simp add: mask_eq_exp_minus_1 push_bit_of_1) 
   7.720 +
   7.721 +lemma uint_sshiftr_eq [code]:
   7.722 +  \<open>uint (w >>> n) = take_bit LENGTH('a) (sint w div 2 ^  n)\<close>
   7.723 +  for w :: \<open>'a::len word\<close>
   7.724 +  by transfer (simp flip: drop_bit_eq_div)
   7.725 +
   7.726 +lemma sshift1_code [code]:
   7.727 +  \<open>sshiftr1 w = w >>> 1\<close>
   7.728 +  by transfer (simp add: drop_bit_Suc)
   7.729  
   7.730  
   7.731  subsection \<open>Rotation\<close>
   7.732  
   7.733 -definition rotater1 :: "'a list \<Rightarrow> 'a list"
   7.734 -  where "rotater1 ys =
   7.735 -    (case ys of [] \<Rightarrow> [] | x # xs \<Rightarrow> last ys # butlast ys)"
   7.736 -
   7.737 -definition rotater :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list"
   7.738 -  where "rotater n = rotater1 ^^ n"
   7.739 -
   7.740 -definition word_rotr :: "nat \<Rightarrow> 'a::len word \<Rightarrow> 'a::len word"
   7.741 -  where "word_rotr n w = of_bl (rotater n (to_bl w))"
   7.742 -
   7.743 -definition word_rotl :: "nat \<Rightarrow> 'a::len word \<Rightarrow> 'a::len word"
   7.744 -  where "word_rotl n w = of_bl (rotate n (to_bl w))"
   7.745 -
   7.746 -definition word_roti :: "int \<Rightarrow> 'a::len word \<Rightarrow> 'a::len word"
   7.747 -  where "word_roti i w =
   7.748 -    (if i \<ge> 0 then word_rotr (nat i) w else word_rotl (nat (- i)) w)"
   7.749 -
   7.750 -
   7.751 +lemma length_to_bl_eq:
   7.752 +  \<open>length (to_bl w) = LENGTH('a)\<close>
   7.753 +  for w :: \<open>'a::len word\<close>
   7.754 +  by transfer simp
   7.755 +
   7.756 +lift_definition word_rotr :: \<open>nat \<Rightarrow> 'a::len word \<Rightarrow> 'a::len word\<close>
   7.757 +  is \<open>\<lambda>n k. concat_bit (LENGTH('a) - n mod LENGTH('a))
   7.758 +    (drop_bit (n mod LENGTH('a)) (take_bit LENGTH('a) k))
   7.759 +    (take_bit (n mod LENGTH('a)) k)\<close>
   7.760 +  subgoal for n k l
   7.761 +    apply (simp add: concat_bit_def nat_le_iff less_imp_le
   7.762 +      take_bit_tightened [of \<open>LENGTH('a)\<close> k l \<open>n mod LENGTH('a::len)\<close>])
   7.763 +    done
   7.764 +  done
   7.765 +
   7.766 +lift_definition word_rotl :: \<open>nat \<Rightarrow> 'a::len word \<Rightarrow> 'a::len word\<close>
   7.767 +  is \<open>\<lambda>n k. concat_bit (n mod LENGTH('a))
   7.768 +    (drop_bit (LENGTH('a) - n mod LENGTH('a)) (take_bit LENGTH('a) k))
   7.769 +    (take_bit (LENGTH('a) - n mod LENGTH('a)) k)\<close>
   7.770 +  subgoal for n k l
   7.771 +    apply (simp add: concat_bit_def nat_le_iff less_imp_le
   7.772 +      take_bit_tightened [of \<open>LENGTH('a)\<close> k l \<open>LENGTH('a) - n mod LENGTH('a::len)\<close>])
   7.773 +    done
   7.774 +  done
   7.775 +
   7.776 +lift_definition word_roti :: \<open>int \<Rightarrow> 'a::len word \<Rightarrow> 'a::len word\<close>
   7.777 +  is \<open>\<lambda>r k. concat_bit (LENGTH('a) - nat (r mod int LENGTH('a)))
   7.778 +    (drop_bit (nat (r mod int LENGTH('a))) (take_bit LENGTH('a) k))
   7.779 +    (take_bit (nat (r mod int LENGTH('a))) k)\<close>
   7.780 +  subgoal for r k l
   7.781 +    apply (simp add: concat_bit_def nat_le_iff less_imp_le
   7.782 +      take_bit_tightened [of \<open>LENGTH('a)\<close> k l \<open>nat (r mod int LENGTH('a::len))\<close>])
   7.783 +    done
   7.784 +  done
   7.785 +
   7.786 +lemma word_rotl_eq_word_rotr [code]:
   7.787 +  \<open>word_rotl n = (word_rotr (LENGTH('a) - n mod LENGTH('a)) :: 'a::len word \<Rightarrow> 'a word)\<close>
   7.788 +  by (rule ext, cases \<open>n mod LENGTH('a) = 0\<close>; transfer) simp_all
   7.789 +
   7.790 +lemma word_roti_eq_word_rotr_word_rotl [code]:
   7.791 +  \<open>word_roti i w =
   7.792 +    (if i \<ge> 0 then word_rotr (nat i) w else word_rotl (nat (- i)) w)\<close>
   7.793 +proof (cases \<open>i \<ge> 0\<close>)
   7.794 +  case True
   7.795 +  moreover define n where \<open>n = nat i\<close>
   7.796 +  ultimately have \<open>i = int n\<close>
   7.797 +    by simp
   7.798 +  moreover have \<open>word_roti (int n) = (word_rotr n :: _ \<Rightarrow> 'a word)\<close>
   7.799 +    by (rule ext, transfer) (simp add: nat_mod_distrib)
   7.800 +  ultimately show ?thesis
   7.801 +    by simp
   7.802 +next
   7.803 +  case False
   7.804 +  moreover define n where \<open>n = nat (- i)\<close>
   7.805 +  ultimately have \<open>i = - int n\<close> \<open>n > 0\<close>
   7.806 +    by simp_all
   7.807 +  moreover have \<open>word_roti (- int n) = (word_rotl n :: _ \<Rightarrow> 'a word)\<close>
   7.808 +    by (rule ext, transfer)
   7.809 +      (simp add: zmod_zminus1_eq_if flip: of_nat_mod of_nat_diff)
   7.810 +  ultimately show ?thesis
   7.811 +    by simp
   7.812 +qed
   7.813 +
   7.814 +lemma bit_word_rotr_iff:
   7.815 +  \<open>bit (word_rotr m w) n \<longleftrightarrow>
   7.816 +    n < LENGTH('a) \<and> bit w ((n + m) mod LENGTH('a))\<close>
   7.817 +  for w :: \<open>'a::len word\<close>
   7.818 +proof transfer
   7.819 +  fix k :: int and m n :: nat
   7.820 +  define q where \<open>q = m mod LENGTH('a)\<close>
   7.821 +  have \<open>q < LENGTH('a)\<close> 
   7.822 +    by (simp add: q_def)
   7.823 +  then have \<open>q \<le> LENGTH('a)\<close>
   7.824 +    by simp
   7.825 +  have \<open>m mod LENGTH('a) = q\<close>
   7.826 +    by (simp add: q_def)
   7.827 +  moreover have \<open>(n + m) mod LENGTH('a) = (n + q) mod LENGTH('a)\<close>
   7.828 +    by (subst mod_add_right_eq [symmetric]) (simp add: \<open>m mod LENGTH('a) = q\<close>)
   7.829 +  moreover have \<open>n < LENGTH('a) \<and>
   7.830 +    bit (concat_bit (LENGTH('a) - q) (drop_bit q (take_bit LENGTH('a) k)) (take_bit q k)) n \<longleftrightarrow>
   7.831 +    n < LENGTH('a) \<and> bit k ((n + q) mod LENGTH('a))\<close>
   7.832 +    using \<open>q < LENGTH('a)\<close>
   7.833 +    by (cases \<open>q + n \<ge> LENGTH('a)\<close>)
   7.834 +     (auto simp add: bit_concat_bit_iff bit_drop_bit_eq
   7.835 +        bit_take_bit_iff le_mod_geq ac_simps)
   7.836 +  ultimately show \<open>n < LENGTH('a) \<and>
   7.837 +    bit (concat_bit (LENGTH('a) - m mod LENGTH('a))
   7.838 +      (drop_bit (m mod LENGTH('a)) (take_bit LENGTH('a) k))
   7.839 +      (take_bit (m mod LENGTH('a)) k)) n
   7.840 +    \<longleftrightarrow> n < LENGTH('a) \<and>
   7.841 +      (n + m) mod LENGTH('a) < LENGTH('a) \<and>
   7.842 +      bit k ((n + m) mod LENGTH('a))\<close>
   7.843 +    by simp
   7.844 +qed
   7.845 +
   7.846 +lemma bit_word_rotl_iff:
   7.847 +  \<open>bit (word_rotl m w) n \<longleftrightarrow>
   7.848 +    n < LENGTH('a) \<and> bit w ((n + (LENGTH('a) - m mod LENGTH('a))) mod LENGTH('a))\<close>
   7.849 +  for w :: \<open>'a::len word\<close>
   7.850 +  by (simp add: word_rotl_eq_word_rotr bit_word_rotr_iff)
   7.851 +
   7.852 +lemma bit_word_roti_iff:
   7.853 +  \<open>bit (word_roti k w) n \<longleftrightarrow>
   7.854 +    n < LENGTH('a) \<and> bit w (nat ((int n + k) mod int LENGTH('a)))\<close>
   7.855 +  for w :: \<open>'a::len word\<close>
   7.856 +proof transfer
   7.857 +  fix k l :: int and n :: nat
   7.858 +  define m where \<open>m = nat (k mod int LENGTH('a))\<close>
   7.859 +  have \<open>m < LENGTH('a)\<close> 
   7.860 +    by (simp add: nat_less_iff m_def)
   7.861 +  then have \<open>m \<le> LENGTH('a)\<close>
   7.862 +    by simp
   7.863 +  have \<open>k mod int LENGTH('a) = int m\<close>
   7.864 +    by (simp add: nat_less_iff m_def)
   7.865 +  moreover have \<open>(int n + k) mod int LENGTH('a) = int ((n + m) mod LENGTH('a))\<close>
   7.866 +    by (subst mod_add_right_eq [symmetric]) (simp add: of_nat_mod \<open>k mod int LENGTH('a) = int m\<close>)
   7.867 +  moreover have \<open>n < LENGTH('a) \<and>
   7.868 +    bit (concat_bit (LENGTH('a) - m) (drop_bit m (take_bit LENGTH('a) l)) (take_bit m l)) n \<longleftrightarrow>
   7.869 +    n < LENGTH('a) \<and> bit l ((n + m) mod LENGTH('a))\<close>
   7.870 +    using \<open>m < LENGTH('a)\<close>
   7.871 +    by (cases \<open>m + n \<ge> LENGTH('a)\<close>)
   7.872 +     (auto simp add: bit_concat_bit_iff bit_drop_bit_eq
   7.873 +        bit_take_bit_iff nat_less_iff not_le not_less ac_simps
   7.874 +        le_diff_conv le_mod_geq)
   7.875 +  ultimately show \<open>n < LENGTH('a)
   7.876 +    \<and> bit (concat_bit (LENGTH('a) - nat (k mod int LENGTH('a)))
   7.877 +             (drop_bit (nat (k mod int LENGTH('a))) (take_bit LENGTH('a) l))
   7.878 +             (take_bit (nat (k mod int LENGTH('a))) l)) n \<longleftrightarrow>
   7.879 +       n < LENGTH('a) 
   7.880 +    \<and> nat ((int n + k) mod int LENGTH('a)) < LENGTH('a)
   7.881 +    \<and> bit l (nat ((int n + k) mod int LENGTH('a)))\<close>
   7.882 +    by simp
   7.883 +qed
   7.884 +
   7.885 +lemma uint_word_rotr_eq [code]:
   7.886 +  \<open>uint (word_rotr n w) = concat_bit (LENGTH('a) - n mod LENGTH('a))
   7.887 +    (drop_bit (n mod LENGTH('a)) (uint w))
   7.888 +    (uint (take_bit (n mod LENGTH('a)) w))\<close>
   7.889 +  for w :: \<open>'a::len word\<close>
   7.890 +  apply transfer
   7.891 +  apply (simp add: concat_bit_def take_bit_drop_bit push_bit_take_bit min_def)
   7.892 +  using mod_less_divisor not_less apply blast
   7.893 +  done
   7.894 +
   7.895 +lemma word_rotr_eq:
   7.896 +  \<open>word_rotr n w = of_bl (rotater n (to_bl w))\<close>
   7.897 +  apply (rule bit_word_eqI)
   7.898 +  subgoal for n
   7.899 +    apply (cases \<open>n < LENGTH('a)\<close>)
   7.900 +     apply (simp_all add: bit_word_rotr_iff bit_of_bl_iff rotater_rev length_to_bl_eq nth_rotate rev_to_bl_eq ac_simps)
   7.901 +    done
   7.902 +  done
   7.903 +
   7.904 +lemma word_rotl_eq:
   7.905 +  \<open>word_rotl n w = of_bl (rotate n (to_bl w))\<close>
   7.906 +proof -
   7.907 +  have \<open>rotate n (to_bl w) = rev (rotater n (rev (to_bl w)))\<close>
   7.908 +    by (simp add: rotater_rev')
   7.909 +  then show ?thesis
   7.910 +    apply (simp add: word_rotl_eq_word_rotr bit_of_bl_iff length_to_bl_eq rev_to_bl_eq)
   7.911 +    apply (rule bit_word_eqI)
   7.912 +    subgoal for n
   7.913 +      apply (cases \<open>n < LENGTH('a)\<close>)
   7.914 +       apply (simp_all add: bit_word_rotr_iff bit_of_bl_iff nth_rotater)
   7.915 +      done
   7.916 +    done
   7.917 +qed
   7.918 +
   7.919 +    
   7.920  subsection \<open>Split and cat operations\<close>
   7.921  
   7.922 -definition word_cat :: "'a::len word \<Rightarrow> 'b::len word \<Rightarrow> 'c::len word"
   7.923 -  where "word_cat a b = word_of_int (bin_cat (uint a) (LENGTH('b)) (uint b))"
   7.924 +lift_definition word_cat :: \<open>'a::len word \<Rightarrow> 'b::len word \<Rightarrow> 'c::len word\<close>
   7.925 +  is \<open>\<lambda>k l. concat_bit LENGTH('b) l (take_bit LENGTH('a) k)\<close>
   7.926 +  by (simp add: bit_eq_iff bit_concat_bit_iff bit_take_bit_iff)
   7.927  
   7.928  lemma word_cat_eq:
   7.929    \<open>(word_cat v w :: 'c::len word) = push_bit LENGTH('b) (ucast v) + ucast w\<close>
   7.930    for v :: \<open>'a::len word\<close> and w :: \<open>'b::len word\<close>
   7.931 -  apply (simp add: word_cat_def bin_cat_eq_push_bit_add_take_bit ucast_def)
   7.932 -  apply transfer apply simp
   7.933 -  done
   7.934 +  by transfer (simp add: bin_cat_eq_push_bit_add_take_bit)
   7.935 +
   7.936 +lemma word_cat_eq' [code]:
   7.937 +  \<open>word_cat a b = word_of_int (concat_bit LENGTH('b) (uint b) (uint a))\<close>
   7.938 +  for a :: \<open>'a::len word\<close> and b :: \<open>'b::len word\<close>
   7.939 +  by transfer simp
   7.940  
   7.941  lemma bit_word_cat_iff:
   7.942    \<open>bit (word_cat v w :: 'c::len word) n \<longleftrightarrow> n < LENGTH('c) \<and> (if n < LENGTH('b) then bit w n else bit v (n - LENGTH('b)))\<close> 
   7.943    for v :: \<open>'a::len word\<close> and w :: \<open>'b::len word\<close>
   7.944 -  by (auto simp add: word_cat_def bit_word_of_int_iff bin_nth_cat bit_uint_iff not_less bit_imp_le_length)
   7.945 +  by transfer (simp add: bit_concat_bit_iff bit_take_bit_iff)
   7.946  
   7.947  definition word_split :: "'a::len word \<Rightarrow> 'b::len word \<times> 'c::len word"
   7.948    where "word_split a =
   7.949 @@ -1173,7 +1618,7 @@
   7.950  lemmas td_sint = word_sint.td
   7.951  
   7.952  lemma to_bl_def': "(to_bl :: 'a::len word \<Rightarrow> bool list) = bin_to_bl (LENGTH('a)) \<circ> uint"
   7.953 -  by (auto simp: to_bl_def)
   7.954 +  by transfer (simp add: fun_eq_iff)
   7.955  
   7.956  lemma uints_mod: "uints n = range (\<lambda>w. w mod 2 ^ n)"
   7.957    by (fact uints_def [unfolded no_bintr_alt1])
   7.958 @@ -1207,11 +1652,11 @@
   7.959  
   7.960  lemma unat_bintrunc [simp]:
   7.961    "unat (numeral bin :: 'a::len word) = nat (bintrunc (LENGTH('a)) (numeral bin))"
   7.962 -  by (simp only: unat_def uint_bintrunc)
   7.963 +  by transfer simp
   7.964  
   7.965  lemma unat_bintrunc_neg [simp]:
   7.966    "unat (- numeral bin :: 'a::len word) = nat (bintrunc (LENGTH('a)) (- numeral bin))"
   7.967 -  by (simp only: unat_def uint_bintrunc_neg)
   7.968 +  by transfer simp
   7.969  
   7.970  lemma size_0_eq: "size w = 0 \<Longrightarrow> v = w"
   7.971    for v w :: "'a::len word"
   7.972 @@ -1262,7 +1707,7 @@
   7.973    by (fact uint_ge_0 [THEN leD, THEN antisym_conv1])
   7.974  
   7.975  lemma uint_nat: "uint w = int (unat w)"
   7.976 -  by (auto simp: unat_def)
   7.977 +  by transfer simp
   7.978  
   7.979  lemma uint_numeral: "uint (numeral b :: 'a::len word) = numeral b mod 2 ^ LENGTH('a)"
   7.980    by (simp only: word_numeral_alt int_word_uint)
   7.981 @@ -1271,12 +1716,7 @@
   7.982    by (simp only: word_neg_numeral_alt int_word_uint)
   7.983  
   7.984  lemma unat_numeral: "unat (numeral b :: 'a::len word) = numeral b mod 2 ^ LENGTH('a)"
   7.985 -  apply (unfold unat_def)
   7.986 -  apply (clarsimp simp only: uint_numeral)
   7.987 -  apply (rule nat_mod_distrib [THEN trans])
   7.988 -    apply (rule zero_le_numeral)
   7.989 -   apply (simp_all add: nat_power_eq)
   7.990 -  done
   7.991 +  by transfer (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq)
   7.992  
   7.993  lemma sint_numeral:
   7.994    "sint (numeral b :: 'a::len word) =
   7.995 @@ -1303,17 +1743,17 @@
   7.996  
   7.997  lemma word_int_case_wi:
   7.998    "word_int_case f (word_of_int i :: 'b word) = f (i mod 2 ^ LENGTH('b::len))"
   7.999 -  by (simp add: word_int_case_def word_uint.eq_norm)
  7.1000 +  by transfer (simp add: take_bit_eq_mod)
  7.1001  
  7.1002  lemma word_int_split:
  7.1003    "P (word_int_case f x) =
  7.1004      (\<forall>i. x = (word_of_int i :: 'b::len word) \<and> 0 \<le> i \<and> i < 2 ^ LENGTH('b) \<longrightarrow> P (f i))"
  7.1005 -  by (auto simp: word_int_case_def word_uint.eq_norm)
  7.1006 +  by transfer (auto simp add: take_bit_eq_mod)
  7.1007  
  7.1008  lemma word_int_split_asm:
  7.1009    "P (word_int_case f x) =
  7.1010      (\<nexists>n. x = (word_of_int n :: 'b::len word) \<and> 0 \<le> n \<and> n < 2 ^ LENGTH('b::len) \<and> \<not> P (f n))"
  7.1011 -  by (auto simp: word_int_case_def word_uint.eq_norm)
  7.1012 +  by transfer (auto simp add: take_bit_eq_mod)
  7.1013  
  7.1014  lemmas uint_range' = word_uint.Rep [unfolded uints_num mem_Collect_eq]
  7.1015  lemmas sint_range' = word_sint.Rep [unfolded One_nat_def sints_num mem_Collect_eq]
  7.1016 @@ -1411,7 +1851,7 @@
  7.1017      (to_bl :: 'a::len word \<Rightarrow> bool list)
  7.1018      of_bl
  7.1019      {bl. length bl = LENGTH('a)}"
  7.1020 -  apply (unfold type_definition_def of_bl_def to_bl_def)
  7.1021 +  apply (unfold type_definition_def of_bl.abs_eq to_bl_eq)
  7.1022    apply (simp add: word_ubin.eq_norm)
  7.1023    apply safe
  7.1024    apply (drule sym)
  7.1025 @@ -1446,9 +1886,10 @@
  7.1026    by (fact length_bl_gt_0 [THEN gr_implies_not0])
  7.1027  
  7.1028  lemma hd_bl_sign_sint: "hd (to_bl w) = (bin_sign (sint w) = -1)"
  7.1029 -  apply (unfold to_bl_def sint_uint)
  7.1030 -  apply (rule trans [OF _ bl_sbin_sign])
  7.1031 -  apply simp
  7.1032 +  apply transfer
  7.1033 +  apply (auto simp add: bin_sign_def)
  7.1034 +  using bin_sign_lem bl_sbin_sign apply fastforce
  7.1035 +  using bin_sign_lem bl_sbin_sign apply force
  7.1036    done
  7.1037  
  7.1038  lemma of_bl_drop':
  7.1039 @@ -1461,15 +1902,11 @@
  7.1040    by (auto simp add: of_bl_def word_test_bit_def word_size
  7.1041        word_ubin.eq_norm nth_bintr bin_nth_of_bl)
  7.1042  
  7.1043 -lemma bit_of_bl_iff:
  7.1044 -  \<open>bit (of_bl bs :: 'a word) n \<longleftrightarrow> rev bs ! n \<and> n < LENGTH('a::len) \<and> n < length bs\<close>
  7.1045 -  using test_bit_of_bl [of bs n] by (simp add: test_bit_word_eq)
  7.1046 -
  7.1047  lemma no_of_bl: "(numeral bin ::'a::len word) = of_bl (bin_to_bl (LENGTH('a)) (numeral bin))"
  7.1048    by (simp add: of_bl_def)
  7.1049  
  7.1050  lemma uint_bl: "to_bl w = bin_to_bl (size w) (uint w)"
  7.1051 -  by (auto simp: word_size to_bl_def)
  7.1052 +  by transfer simp
  7.1053  
  7.1054  lemma to_bl_bin: "bl_to_bin (to_bl w) = uint w"
  7.1055    by (simp add: uint_bl word_size)
  7.1056 @@ -1525,21 +1962,20 @@
  7.1057  \<close>
  7.1058  
  7.1059  lemma bit_ucast_iff:
  7.1060 -  \<open>Parity.bit (ucast a :: 'a::len word) n \<longleftrightarrow> n < LENGTH('a::len) \<and> Parity.bit a n\<close>
  7.1061 -  by (simp add: ucast_def, transfer) (auto simp add: bit_take_bit_iff)
  7.1062 -
  7.1063 -lemma ucast_id: "ucast w = w"
  7.1064 -  by (auto simp: ucast_def)
  7.1065 -
  7.1066 -lemma scast_id: "scast w = w"
  7.1067 -  by (auto simp: scast_def)
  7.1068 +  \<open>bit (ucast a :: 'a::len word) n \<longleftrightarrow> n < LENGTH('a::len) \<and> Parity.bit a n\<close>
  7.1069 +  by transfer (simp add: bit_take_bit_iff)
  7.1070 +
  7.1071 +lemma ucast_id [simp]: "ucast w = w"
  7.1072 +  by transfer simp
  7.1073 +
  7.1074 +lemma scast_id [simp]: "scast w = w"
  7.1075 +  by transfer simp
  7.1076  
  7.1077  lemma ucast_bl: "ucast w = of_bl (to_bl w)"
  7.1078 -  by (auto simp: ucast_def of_bl_def uint_bl word_size)
  7.1079 +  by transfer simp
  7.1080  
  7.1081  lemma nth_ucast: "(ucast w::'a::len word) !! n = (w !! n \<and> n < LENGTH('a))"
  7.1082 -  by (simp add: ucast_def test_bit_bin word_ubin.eq_norm nth_bintr word_size)
  7.1083 -    (fast elim!: bin_nth_uint_imp)
  7.1084 +  by transfer (simp add: bit_take_bit_iff ac_simps)
  7.1085  
  7.1086  context
  7.1087    includes lifting_syntax
  7.1088 @@ -1559,162 +1995,130 @@
  7.1089  lemma ucast_bintr [simp]:
  7.1090    "ucast (numeral w :: 'a::len word) =
  7.1091      word_of_int (bintrunc (LENGTH('a)) (numeral w))"
  7.1092 -  by (simp add: ucast_def)
  7.1093 +  by transfer simp
  7.1094  
  7.1095  (* TODO: neg_numeral *)
  7.1096  
  7.1097  lemma scast_sbintr [simp]:
  7.1098    "scast (numeral w ::'a::len word) =
  7.1099      word_of_int (sbintrunc (LENGTH('a) - Suc 0) (numeral w))"
  7.1100 -  by (simp add: scast_def)
  7.1101 +  by transfer simp
  7.1102  
  7.1103  lemma source_size: "source_size (c::'a::len word \<Rightarrow> _) = LENGTH('a)"
  7.1104 -  unfolding source_size_def word_size Let_def ..
  7.1105 +  by transfer simp
  7.1106  
  7.1107  lemma target_size: "target_size (c::_ \<Rightarrow> 'b::len word) = LENGTH('b)"
  7.1108 -  unfolding target_size_def word_size Let_def ..
  7.1109 +  by transfer simp
  7.1110  
  7.1111  lemma is_down: "is_down c \<longleftrightarrow> LENGTH('b) \<le> LENGTH('a)"
  7.1112    for c :: "'a::len word \<Rightarrow> 'b::len word"
  7.1113 -  by (simp only: is_down_def source_size target_size)
  7.1114 +  by transfer simp
  7.1115  
  7.1116  lemma is_up: "is_up c \<longleftrightarrow> LENGTH('a) \<le> LENGTH('b)"
  7.1117    for c :: "'a::len word \<Rightarrow> 'b::len word"
  7.1118 -  by (simp only: is_up_def source_size target_size)
  7.1119 -
  7.1120 -lemmas is_up_down = trans [OF is_up is_down [symmetric]]
  7.1121 -
  7.1122 -lemma down_cast_same [OF refl]: "uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc = scast"
  7.1123 -  apply (unfold is_down)
  7.1124 -  apply safe
  7.1125 -  apply (rule ext)
  7.1126 -  apply (unfold ucast_def scast_def uint_sint)
  7.1127 -  apply (rule word_ubin.norm_eq_iff [THEN iffD1])
  7.1128 -  apply simp
  7.1129 -  done
  7.1130 -
  7.1131 -lemma word_rev_tf:
  7.1132 -  "to_bl (of_bl bl::'a::len word) =
  7.1133 -    rev (takefill False (LENGTH('a)) (rev bl))"
  7.1134 -  by (auto simp: of_bl_def uint_bl bl_bin_bl_rtf word_ubin.eq_norm word_size)
  7.1135 -
  7.1136 -lemma word_rep_drop:
  7.1137 -  "to_bl (of_bl bl::'a::len word) =
  7.1138 -    replicate (LENGTH('a) - length bl) False @
  7.1139 -    drop (length bl - LENGTH('a)) bl"
  7.1140 -  by (simp add: word_rev_tf takefill_alt rev_take)
  7.1141 -
  7.1142 -lemma to_bl_ucast:
  7.1143 -  "to_bl (ucast (w::'b::len word) ::'a::len word) =
  7.1144 -    replicate (LENGTH('a) - LENGTH('b)) False @
  7.1145 -    drop (LENGTH('b) - LENGTH('a)) (to_bl w)"
  7.1146 -  apply (unfold ucast_bl)
  7.1147 -  apply (rule trans)
  7.1148 -   apply (rule word_rep_drop)
  7.1149 -  apply simp
  7.1150 -  done
  7.1151 -
  7.1152 -lemma ucast_up_app [OF refl]:
  7.1153 -  "uc = ucast \<Longrightarrow> source_size uc + n = target_size uc \<Longrightarrow>
  7.1154 -    to_bl (uc w) = replicate n False @ (to_bl w)"
  7.1155 -  by (auto simp add : source_size target_size to_bl_ucast)
  7.1156 -
  7.1157 -lemma ucast_down_drop [OF refl]:
  7.1158 -  "uc = ucast \<Longrightarrow> source_size uc = target_size uc + n \<Longrightarrow>
  7.1159 -    to_bl (uc w) = drop n (to_bl w)"
  7.1160 -  by (auto simp add : source_size target_size to_bl_ucast)
  7.1161 -
  7.1162 -lemma scast_down_drop [OF refl]:
  7.1163 -  "sc = scast \<Longrightarrow> source_size sc = target_size sc + n \<Longrightarrow>
  7.1164 -    to_bl (sc w) = drop n (to_bl w)"
  7.1165 -  apply (subgoal_tac "sc = ucast")
  7.1166 -   apply safe
  7.1167 -   apply simp
  7.1168 -   apply (erule ucast_down_drop)
  7.1169 -  apply (rule down_cast_same [symmetric])
  7.1170 -  apply (simp add : source_size target_size is_down)
  7.1171 -  done
  7.1172 -
  7.1173 -lemma sint_up_scast [OF refl]: "sc = scast \<Longrightarrow> is_up sc \<Longrightarrow> sint (sc w) = sint w"
  7.1174 -  apply (unfold is_up)
  7.1175 -  apply safe
  7.1176 -  apply (simp add: scast_def word_sbin.eq_norm)
  7.1177 -  apply (rule box_equals)
  7.1178 -    prefer 3
  7.1179 -    apply (rule word_sbin.norm_Rep)
  7.1180 -   apply (rule sbintrunc_sbintrunc_l)
  7.1181 -   defer
  7.1182 -   apply (subst word_sbin.norm_Rep)
  7.1183 -   apply (rule refl)
  7.1184 -  apply simp
  7.1185 -  done
  7.1186 -
  7.1187 -lemma uint_up_ucast [OF refl]: "uc = ucast \<Longrightarrow> is_up uc \<Longrightarrow> uint (uc w) = uint w"
  7.1188 -  apply (unfold is_up)
  7.1189 -  apply safe
  7.1190 -  apply (rule bin_eqI)
  7.1191 -  apply (fold word_test_bit_def)
  7.1192 -  apply (auto simp add: nth_ucast)
  7.1193 -  apply (auto simp add: test_bit_bin)
  7.1194 -  done
  7.1195 -
  7.1196 -lemma ucast_up_ucast [OF refl]: "uc = ucast \<Longrightarrow> is_up uc \<Longrightarrow> ucast (uc w) = ucast w"
  7.1197 -  apply (simp (no_asm) add: ucast_def)
  7.1198 -  apply (clarsimp simp add: uint_up_ucast)
  7.1199 -  done
  7.1200 -
  7.1201 -lemma scast_up_scast [OF refl]: "sc = scast \<Longrightarrow> is_up sc \<Longrightarrow> scast (sc w) = scast w"
  7.1202 -  apply (simp (no_asm) add: scast_def)
  7.1203 -  apply (clarsimp simp add: sint_up_scast)
  7.1204 -  done
  7.1205 -
  7.1206 -lemma ucast_of_bl_up [OF refl]: "w = of_bl bl \<Longrightarrow> size bl \<le> size w \<Longrightarrow> ucast w = of_bl bl"
  7.1207 -  by (auto simp add : nth_ucast word_size test_bit_of_bl intro!: word_eqI)
  7.1208 -
  7.1209 -lemmas ucast_up_ucast_id = trans [OF ucast_up_ucast ucast_id]
  7.1210 -lemmas scast_up_scast_id = trans [OF scast_up_scast scast_id]
  7.1211 -
  7.1212 -lemmas isduu = is_up_down [where c = "ucast", THEN iffD2]
  7.1213 -lemmas isdus = is_up_down [where c = "scast", THEN iffD2]
  7.1214 +  by transfer simp
  7.1215 +
  7.1216 +lemma is_up_down:
  7.1217 +  \<open>is_up c \<longleftrightarrow> is_down d\<close>
  7.1218 +  for c :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
  7.1219 +  and d :: \<open>'b::len word \<Rightarrow> 'a::len word\<close>
  7.1220 +  by transfer simp
  7.1221 +
  7.1222 +context
  7.1223 +  fixes dummy_types :: \<open>'a::len \<times> 'b::len\<close>
  7.1224 +begin
  7.1225 +
  7.1226 +private abbreviation (input) UCAST :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
  7.1227 +  where \<open>UCAST == ucast\<close>
  7.1228 +
  7.1229 +private abbreviation (input) SCAST :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
  7.1230 +  where \<open>SCAST == scast\<close>
  7.1231 +
  7.1232 +lemma down_cast_same:
  7.1233 +  \<open>UCAST = scast\<close> if \<open>is_down UCAST\<close>
  7.1234 +  by (rule ext, use that in transfer) (simp add: take_bit_signed_take_bit)
  7.1235 +
  7.1236 +lemma sint_up_scast:
  7.1237 +  \<open>sint (SCAST w) = sint w\<close> if \<open>is_up SCAST\<close>
  7.1238 +  using that by transfer (simp add: min_def Suc_leI le_diff_iff)
  7.1239 +
  7.1240 +lemma uint_up_ucast:
  7.1241 +  \<open>uint (UCAST w) = uint w\<close> if \<open>is_up UCAST\<close>
  7.1242 +  using that by transfer (simp add: min_def)
  7.1243 +
  7.1244 +lemma ucast_up_ucast:
  7.1245 +  \<open>ucast (UCAST w) = ucast w\<close> if \<open>is_up UCAST\<close>
  7.1246 +  using that by transfer (simp add: ac_simps)
  7.1247 +
  7.1248 +lemma ucast_up_ucast_id:
  7.1249 +  \<open>ucast (UCAST w) = w\<close> if \<open>is_up UCAST\<close>
  7.1250 +  using that by (simp add: ucast_up_ucast)
  7.1251 +
  7.1252 +lemma scast_up_scast:
  7.1253 +  \<open>scast (SCAST w) = scast w\<close> if \<open>is_up SCAST\<close>
  7.1254 +  using that by transfer (simp add: ac_simps)
  7.1255 +
  7.1256 +lemma scast_up_scast_id:
  7.1257 +  \<open>scast (SCAST w) = w\<close> if \<open>is_up SCAST\<close>
  7.1258 +  using that by (simp add: scast_up_scast)
  7.1259 +
  7.1260 +lemma isduu:
  7.1261 +  \<open>is_up UCAST\<close> if \<open>is_down d\<close>
  7.1262 +    for d :: \<open>'b word \<Rightarrow> 'a word\<close>
  7.1263 +  using that is_up_down [of UCAST d] by simp
  7.1264 +
  7.1265 +lemma isdus:
  7.1266 +  \<open>is_up SCAST\<close> if \<open>is_down d\<close>
  7.1267 +    for d :: \<open>'b word \<Rightarrow> 'a word\<close>
  7.1268 +  using that is_up_down [of SCAST d] by simp
  7.1269 +
  7.1270  lemmas ucast_down_ucast_id = isduu [THEN ucast_up_ucast_id]
  7.1271 -lemmas scast_down_scast_id = isdus [THEN ucast_up_ucast_id]
  7.1272 +lemmas scast_down_scast_id = isdus [THEN scast_up_scast_id]
  7.1273  
  7.1274  lemma up_ucast_surj:
  7.1275 -  "is_up (ucast :: 'b::len word \<Rightarrow> 'a::len word) \<Longrightarrow>
  7.1276 -    surj (ucast :: 'a word \<Rightarrow> 'b word)"
  7.1277 -  by (rule surjI) (erule ucast_up_ucast_id)
  7.1278 +  \<open>surj (ucast :: 'b word \<Rightarrow> 'a word)\<close> if \<open>is_up UCAST\<close>
  7.1279 +  by (rule surjI) (use that in \<open>rule ucast_up_ucast_id\<close>)
  7.1280  
  7.1281  lemma up_scast_surj:
  7.1282 -  "is_up (scast :: 'b::len word \<Rightarrow> 'a::len word) \<Longrightarrow>
  7.1283 -    surj (scast :: 'a word \<Rightarrow> 'b word)"
  7.1284 -  by (rule surjI) (erule scast_up_scast_id)
  7.1285 -
  7.1286 -lemma down_scast_inj:
  7.1287 -  "is_down (scast :: 'b::len word \<Rightarrow> 'a::len word) \<Longrightarrow>
  7.1288 -    inj_on (ucast :: 'a word \<Rightarrow> 'b word) A"
  7.1289 -  by (rule inj_on_inverseI, erule scast_down_scast_id)
  7.1290 +  \<open>surj (scast :: 'b word \<Rightarrow> 'a word)\<close> if \<open>is_up SCAST\<close>
  7.1291 +  by (rule surjI) (use that in \<open>rule scast_up_scast_id\<close>)
  7.1292  
  7.1293  lemma down_ucast_inj:
  7.1294 -  "is_down (ucast :: 'b::len word \<Rightarrow> 'a::len word) \<Longrightarrow>
  7.1295 -    inj_on (ucast :: 'a word \<Rightarrow> 'b word) A"
  7.1296 -  by (rule inj_on_inverseI) (erule ucast_down_ucast_id)
  7.1297 +  \<open>inj_on UCAST A\<close> if \<open>is_down (ucast :: 'b word \<Rightarrow> 'a word)\<close>
  7.1298 +  by (rule inj_on_inverseI) (use that in \<open>rule ucast_down_ucast_id\<close>)
  7.1299 +
  7.1300 +lemma down_scast_inj:
  7.1301 +  \<open>inj_on SCAST A\<close> if \<open>is_down (scast :: 'b word \<Rightarrow> 'a word)\<close>
  7.1302 +  by (rule inj_on_inverseI) (use that in \<open>rule scast_down_scast_id\<close>)
  7.1303 +  
  7.1304 +lemma ucast_down_wi:
  7.1305 +  \<open>UCAST (word_of_int x) = word_of_int x\<close> if \<open>is_down UCAST\<close>
  7.1306 +  using that by transfer simp
  7.1307 +
  7.1308 +lemma ucast_down_no:
  7.1309 +  \<open>UCAST (numeral bin) = numeral bin\<close> if \<open>is_down UCAST\<close>
  7.1310 +  using that by transfer simp
  7.1311 +
  7.1312 +lemma ucast_down_bl:
  7.1313 +  "UCAST (of_bl bl) = of_bl bl" if \<open>is_down UCAST\<close>
  7.1314 +  using that by transfer simp
  7.1315 +
  7.1316 +end
  7.1317  
  7.1318  lemma of_bl_append_same: "of_bl (X @ to_bl w) = w"
  7.1319 -  by (rule word_bl.Rep_eqD) (simp add: word_rep_drop)
  7.1320 -
  7.1321 -lemma ucast_down_wi [OF refl]: "uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc (word_of_int x) = word_of_int x"
  7.1322 -  apply (unfold is_down)
  7.1323 -  apply (clarsimp simp add: ucast_def word_ubin.eq_norm)
  7.1324 -  apply (rule word_ubin.norm_eq_iff [THEN iffD1])
  7.1325 -  apply (erule bintrunc_bintrunc_ge)
  7.1326 +  by transfer (simp add: bl_to_bin_app_cat) 
  7.1327 +
  7.1328 +lemma ucast_of_bl_up:
  7.1329 +  \<open>ucast (of_bl bl :: 'a::len word) = of_bl bl\<close>
  7.1330 +  if \<open>size bl \<le> size (of_bl bl :: 'a::len word)\<close>
  7.1331 +  using that
  7.1332 +  apply transfer
  7.1333 +  apply (rule bit_eqI)
  7.1334 +  apply (auto simp add: bit_take_bit_iff)
  7.1335 +  apply (subst (asm) trunc_bl2bin_len [symmetric])
  7.1336 +  apply (auto simp only: bit_take_bit_iff)
  7.1337    done
  7.1338  
  7.1339 -lemma ucast_down_no [OF refl]: "uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc (numeral bin) = numeral bin"
  7.1340 -  unfolding word_numeral_alt by clarify (rule ucast_down_wi)
  7.1341 -
  7.1342 -lemma ucast_down_bl [OF refl]: "uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc (of_bl bl) = of_bl bl"
  7.1343 -  unfolding of_bl_def by clarify (erule ucast_down_wi)
  7.1344 -
  7.1345  lemmas test_bit_def' = word_test_bit_def [THEN fun_cong]
  7.1346  
  7.1347  lemmas word_log_defs = word_and_def word_or_def word_xor_def word_not_def
  7.1348 @@ -1743,6 +2147,50 @@
  7.1349      apply (metis div_exp_eq mod_div_trivial mult.commute nonzero_mult_div_cancel_left power_Suc0_right power_add zero_neq_numeral)
  7.1350      done
  7.1351  
  7.1352 +lemma word_rev_tf:
  7.1353 +  "to_bl (of_bl bl::'a::len word) =
  7.1354 +    rev (takefill False (LENGTH('a)) (rev bl))"
  7.1355 +  by (auto simp: of_bl_def uint_bl bl_bin_bl_rtf word_ubin.eq_norm word_size)
  7.1356 +
  7.1357 +lemma word_rep_drop:
  7.1358 +  "to_bl (of_bl bl::'a::len word) =
  7.1359 +    replicate (LENGTH('a) - length bl) False @
  7.1360 +    drop (length bl - LENGTH('a)) bl"
  7.1361 +  by (simp add: word_rev_tf takefill_alt rev_take)
  7.1362 +
  7.1363 +lemma to_bl_ucast:
  7.1364 +  "to_bl (ucast (w::'b::len word) ::'a::len word) =
  7.1365 +    replicate (LENGTH('a) - LENGTH('b)) False @
  7.1366 +    drop (LENGTH('b) - LENGTH('a)) (to_bl w)"
  7.1367 +  apply (unfold ucast_bl)
  7.1368 +  apply (rule trans)
  7.1369 +   apply (rule word_rep_drop)
  7.1370 +  apply simp
  7.1371 +  done
  7.1372 +
  7.1373 +lemma ucast_up_app:
  7.1374 +  \<open>to_bl (ucast w :: 'b::len word) = replicate n False @ (to_bl w)\<close>
  7.1375 +    if \<open>source_size (ucast :: 'a word \<Rightarrow> 'b word) + n = target_size (ucast :: 'a word \<Rightarrow> 'b word)\<close>
  7.1376 +    for w :: \<open>'a::len word\<close>
  7.1377 +  using that
  7.1378 +  by (auto simp add : source_size target_size to_bl_ucast)
  7.1379 +
  7.1380 +lemma ucast_down_drop [OF refl]:
  7.1381 +  "uc = ucast \<Longrightarrow> source_size uc = target_size uc + n \<Longrightarrow>
  7.1382 +    to_bl (uc w) = drop n (to_bl w)"
  7.1383 +  by (auto simp add : source_size target_size to_bl_ucast)
  7.1384 +
  7.1385 +lemma scast_down_drop [OF refl]:
  7.1386 +  "sc = scast \<Longrightarrow> source_size sc = target_size sc + n \<Longrightarrow>
  7.1387 +    to_bl (sc w) = drop n (to_bl w)"
  7.1388 +  apply (subgoal_tac "sc = ucast")
  7.1389 +   apply safe
  7.1390 +   apply simp
  7.1391 +   apply (erule ucast_down_drop)
  7.1392 +  apply (rule down_cast_same [symmetric])
  7.1393 +  apply (simp add : source_size target_size is_down)
  7.1394 +  done
  7.1395 +
  7.1396  
  7.1397  subsection \<open>Word Arithmetic\<close>
  7.1398  
  7.1399 @@ -1750,7 +2198,7 @@
  7.1400    by (fact word_less_def)
  7.1401  
  7.1402  lemma signed_linorder: "class.linorder word_sle word_sless"
  7.1403 -  by standard (auto simp: word_sle_def word_sless_def)
  7.1404 +  by (standard; transfer) (auto simp add: signed_take_bit_decr_length_iff)
  7.1405  
  7.1406  interpretation signed: linorder "word_sle" "word_sless"
  7.1407    by (rule signed_linorder)
  7.1408 @@ -1762,8 +2210,8 @@
  7.1409  lemmas word_mod_no [simp] = word_mod_def [of "numeral a" "numeral b"] for a b
  7.1410  lemmas word_less_no [simp] = word_less_def [of "numeral a" "numeral b"] for a b
  7.1411  lemmas word_le_no [simp] = word_le_def [of "numeral a" "numeral b"] for a b
  7.1412 -lemmas word_sless_no [simp] = word_sless_def [of "numeral a" "numeral b"] for a b
  7.1413 -lemmas word_sle_no [simp] = word_sle_def [of "numeral a" "numeral b"] for a b
  7.1414 +lemmas word_sless_no [simp] = word_sless_eq [of "numeral a" "numeral b"] for a b
  7.1415 +lemmas word_sle_no [simp] = word_sle_eq [of "numeral a" "numeral b"] for a b
  7.1416  
  7.1417  lemma word_m1_wi: "- 1 = word_of_int (- 1)"
  7.1418    by (simp add: word_neg_numeral_alt [of Num.One])
  7.1419 @@ -1774,9 +2222,6 @@
  7.1420  lemma word_1_bl: "of_bl [True] = 1"
  7.1421    by (simp add: of_bl_def bl_to_bin_def)
  7.1422  
  7.1423 -lemma uint_eq_0 [simp]: "uint 0 = 0"
  7.1424 -  unfolding word_0_wi word_ubin.eq_norm by simp
  7.1425 -
  7.1426  lemma of_bl_0 [simp]: "of_bl (replicate n False) = 0"
  7.1427    by (simp add: of_bl_def bl_to_bin_rep_False)
  7.1428  
  7.1429 @@ -1787,20 +2232,14 @@
  7.1430    by (simp add: word_uint_eq_iff)
  7.1431  
  7.1432  lemma unat_0_iff: "unat x = 0 \<longleftrightarrow> x = 0"
  7.1433 -  by (auto simp: unat_def nat_eq_iff uint_0_iff)
  7.1434 +  by transfer (auto intro: antisym)
  7.1435  
  7.1436  lemma unat_0 [simp]: "unat 0 = 0"
  7.1437 -  by (auto simp: unat_def)
  7.1438 +  by transfer simp
  7.1439  
  7.1440  lemma size_0_same': "size w = 0 \<Longrightarrow> w = v"
  7.1441    for v w :: "'a::len word"
  7.1442 -  apply (unfold word_size)
  7.1443 -  apply (rule box_equals)
  7.1444 -    defer
  7.1445 -    apply (rule word_uint.Rep_inverse)+
  7.1446 -  apply (rule word_ubin.norm_eq_iff [THEN iffD1])
  7.1447 -  apply simp
  7.1448 -  done
  7.1449 +  by (unfold word_size) simp
  7.1450  
  7.1451  lemmas size_0_same = size_0_same' [unfolded word_size]
  7.1452  
  7.1453 @@ -1811,28 +2250,28 @@
  7.1454    by (auto simp: unat_0_iff [symmetric])
  7.1455  
  7.1456  lemma ucast_0 [simp]: "ucast 0 = 0"
  7.1457 -  by (simp add: ucast_def)
  7.1458 +  by transfer simp
  7.1459  
  7.1460  lemma sint_0 [simp]: "sint 0 = 0"
  7.1461    by (simp add: sint_uint)
  7.1462  
  7.1463  lemma scast_0 [simp]: "scast 0 = 0"
  7.1464 -  by (simp add: scast_def)
  7.1465 +  by transfer simp
  7.1466  
  7.1467  lemma sint_n1 [simp] : "sint (- 1) = - 1"
  7.1468 -  by (simp only: word_m1_wi word_sbin.eq_norm) simp
  7.1469 +  by transfer simp
  7.1470  
  7.1471  lemma scast_n1 [simp]: "scast (- 1) = - 1"
  7.1472 -  by (simp add: scast_def)
  7.1473 +  by transfer simp
  7.1474  
  7.1475  lemma uint_1 [simp]: "uint (1::'a::len word) = 1"
  7.1476 -  by (simp only: word_1_wi word_ubin.eq_norm) simp
  7.1477 +  by transfer simp
  7.1478  
  7.1479  lemma unat_1 [simp]: "unat (1::'a::len word) = 1"
  7.1480 -  by (simp add: unat_def)
  7.1481 +  by transfer simp
  7.1482  
  7.1483  lemma ucast_1 [simp]: "ucast (1::'a::len word) = 1"
  7.1484 -  by (simp add: ucast_def)
  7.1485 +  by transfer simp
  7.1486  
  7.1487  \<comment> \<open>now, to get the weaker results analogous to \<open>word_div\<close>/\<open>mod_def\<close>\<close>
  7.1488  
  7.1489 @@ -1935,15 +2374,13 @@
  7.1490  lemmas word_gt_0_no [simp] = word_gt_0 [of "numeral y"] for y
  7.1491  
  7.1492  lemma word_sless_alt: "a <s b \<longleftrightarrow> sint a < sint b"
  7.1493 -  by (auto simp add: word_sle_def word_sless_def less_le)
  7.1494 +  by (auto simp add: word_sle_eq word_sless_eq less_le)
  7.1495  
  7.1496  lemma word_le_nat_alt: "a \<le> b \<longleftrightarrow> unat a \<le> unat b"
  7.1497 -  unfolding unat_def word_le_def
  7.1498 -  by (rule nat_le_eq_zle [symmetric]) simp
  7.1499 +  by transfer (simp add: nat_le_eq_zle)
  7.1500  
  7.1501  lemma word_less_nat_alt: "a < b \<longleftrightarrow> unat a < unat b"
  7.1502 -  unfolding unat_def word_less_alt
  7.1503 -  by (rule nat_less_eq_zless [symmetric]) simp
  7.1504 +  by transfer (auto simp add: less_le [of 0])
  7.1505  
  7.1506  lemmas unat_mono = word_less_nat_alt [THEN iffD1]
  7.1507  
  7.1508 @@ -1971,9 +2408,10 @@
  7.1509    unfolding word_le_def by (simp add: word_uint.eq_norm)
  7.1510  
  7.1511  lemma udvd_nat_alt: "a udvd b \<longleftrightarrow> (\<exists>n\<ge>0. unat b = n * unat a)"
  7.1512 +  supply nat_uint_eq [simp del]
  7.1513    apply (unfold udvd_def)
  7.1514    apply safe
  7.1515 -   apply (simp add: unat_def nat_mult_distrib)
  7.1516 +   apply (simp add: unat_eq_nat_uint nat_mult_distrib)
  7.1517    apply (simp add: uint_nat)
  7.1518    apply (rule exI)
  7.1519    apply safe
  7.1520 @@ -1987,11 +2425,10 @@
  7.1521    unfolding dvd_def udvd_nat_alt by force
  7.1522  
  7.1523  lemma unat_minus_one:
  7.1524 -  assumes "w \<noteq> 0"
  7.1525 -  shows "unat (w - 1) = unat w - 1"
  7.1526 +  \<open>unat (w - 1) = unat w - 1\<close> if \<open>w \<noteq> 0\<close>
  7.1527  proof -
  7.1528    have "0 \<le> uint w" by (fact uint_nonnegative)
  7.1529 -  moreover from assms have "0 \<noteq> uint w"
  7.1530 +  moreover from that have "0 \<noteq> uint w"
  7.1531      by (simp add: uint_0_iff)
  7.1532    ultimately have "1 \<le> uint w"
  7.1533      by arith
  7.1534 @@ -2000,9 +2437,9 @@
  7.1535    with \<open>1 \<le> uint w\<close> have "(uint w - 1) mod 2 ^ LENGTH('a) = uint w - 1"
  7.1536      by (auto intro: mod_pos_pos_trivial)
  7.1537    with \<open>1 \<le> uint w\<close> have "nat ((uint w - 1) mod 2 ^ LENGTH('a)) = nat (uint w) - 1"
  7.1538 -    by auto
  7.1539 +    by (auto simp del: nat_uint_eq)
  7.1540    then show ?thesis
  7.1541 -    by (simp only: unat_def int_word_uint word_arith_wis mod_diff_right_eq)
  7.1542 +    by (simp only: unat_eq_nat_uint int_word_uint word_arith_wis mod_diff_right_eq)
  7.1543  qed
  7.1544  
  7.1545  lemma measure_unat: "p \<noteq> 0 \<Longrightarrow> unat (p - 1) < unat p"
  7.1546 @@ -2090,10 +2527,7 @@
  7.1547  lemma uint_split:
  7.1548    "P (uint x) = (\<forall>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^LENGTH('a) \<longrightarrow> P i)"
  7.1549    for x :: "'a::len word"
  7.1550 -  apply (fold word_int_case_def)
  7.1551 -  apply (auto dest!: word_of_int_inverse simp: int_word_uint
  7.1552 -      split: word_int_split)
  7.1553 -  done
  7.1554 +  by transfer (auto simp add: take_bit_eq_mod take_bit_int_less_exp)
  7.1555  
  7.1556  lemma uint_split_asm:
  7.1557    "P (uint x) = (\<nexists>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^LENGTH('a) \<and> \<not> P i)"
  7.1558 @@ -2333,35 +2767,27 @@
  7.1559  
  7.1560  \<comment> \<open>links with \<open>rbl\<close> operations\<close>
  7.1561  lemma word_succ_rbl: "to_bl w = bl \<Longrightarrow> to_bl (word_succ w) = rev (rbl_succ (rev bl))"
  7.1562 -  apply (unfold word_succ_alt)
  7.1563 -  apply clarify
  7.1564 -  apply (simp add: to_bl_of_bin)
  7.1565 -  apply (simp add: to_bl_def rbl_succ)
  7.1566 -  done
  7.1567 +  by transfer (simp add: rbl_succ)
  7.1568  
  7.1569  lemma word_pred_rbl: "to_bl w = bl \<Longrightarrow> to_bl (word_pred w) = rev (rbl_pred (rev bl))"
  7.1570 -  apply (unfold word_pred_alt)
  7.1571 -  apply clarify
  7.1572 -  apply (simp add: to_bl_of_bin)
  7.1573 -  apply (simp add: to_bl_def rbl_pred)
  7.1574 -  done
  7.1575 +  by transfer (simp add: rbl_pred)
  7.1576  
  7.1577  lemma word_add_rbl:
  7.1578    "to_bl v = vbl \<Longrightarrow> to_bl w = wbl \<Longrightarrow>
  7.1579      to_bl (v + w) = rev (rbl_add (rev vbl) (rev wbl))"
  7.1580 -  apply (unfold word_add_def)
  7.1581 -  apply clarify
  7.1582 -  apply (simp add: to_bl_of_bin)
  7.1583 -  apply (simp add: to_bl_def rbl_add)
  7.1584 +  apply transfer
  7.1585 +  apply (drule sym)
  7.1586 +  apply (drule sym)
  7.1587 +  apply (simp add: rbl_add)
  7.1588    done
  7.1589  
  7.1590  lemma word_mult_rbl:
  7.1591    "to_bl v = vbl \<Longrightarrow> to_bl w = wbl \<Longrightarrow>
  7.1592      to_bl (v * w) = rev (rbl_mult (rev vbl) (rev wbl))"
  7.1593 -  apply (unfold word_mult_def)
  7.1594 -  apply clarify
  7.1595 -  apply (simp add: to_bl_of_bin)
  7.1596 -  apply (simp add: to_bl_def rbl_mult)
  7.1597 +  apply transfer
  7.1598 +  apply (drule sym)
  7.1599 +  apply (drule sym)
  7.1600 +  apply (simp add: rbl_mult)
  7.1601    done
  7.1602  
  7.1603  lemma rtb_rbl_ariths:
  7.1604 @@ -2401,10 +2827,9 @@
  7.1605  lemma td_ext_unat [OF refl]:
  7.1606    "n = LENGTH('a::len) \<Longrightarrow>
  7.1607      td_ext (unat :: 'a word \<Rightarrow> nat) of_nat (unats n) (\<lambda>i. i mod 2 ^ n)"
  7.1608 -  apply (unfold td_ext_def' unat_def word_of_nat unats_uints)
  7.1609 -  apply (auto intro!: imageI simp add : word_of_int_hom_syms)
  7.1610 -   apply (erule word_uint.Abs_inverse [THEN arg_cong])
  7.1611 -  apply (simp add: int_word_uint nat_mod_distrib nat_power_eq)
  7.1612 +  apply (standard; transfer)
  7.1613 +     apply (simp_all add: unats_def take_bit_int_less_exp take_bit_of_nat take_bit_eq_self)
  7.1614 +  apply (simp add: take_bit_eq_mod)
  7.1615    done
  7.1616  
  7.1617  lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm]
  7.1618 @@ -2543,9 +2968,10 @@
  7.1619      (if unat y \<le> unat x
  7.1620       then unat x - unat y
  7.1621       else unat x + 2 ^ size x - unat y)"
  7.1622 +  supply nat_uint_eq [simp del]
  7.1623    apply (unfold word_size)
  7.1624    apply (simp add: un_ui_le)
  7.1625 -  apply (auto simp add: unat_def uint_sub_if')
  7.1626 +  apply (auto simp add: unat_eq_nat_uint uint_sub_if')
  7.1627     apply (rule nat_diff_distrib)
  7.1628      prefer 3
  7.1629      apply (simp add: algebra_simps)
  7.1630 @@ -2566,15 +2992,15 @@
  7.1631  
  7.1632  lemma unat_div:
  7.1633    \<open>unat (x div y) = unat x div unat y\<close>
  7.1634 -  by (simp add: unat_def uint_div add: nat_div_distrib)
  7.1635 +  by (simp add: uint_div nat_div_distrib flip: nat_uint_eq)
  7.1636  
  7.1637  lemma uint_mod:
  7.1638    \<open>uint (x mod y) = uint x mod uint y\<close>
  7.1639    by (metis (no_types, lifting) le_less_trans mod_by_0 mod_le_divisor mod_less neq0_conv uint_nat unat_lt2p unat_word_ariths(7) zmod_int)
  7.1640    
  7.1641 -lemma unat_mod: "unat (x mod y) = unat x mod unat y"
  7.1642 -  for x y :: "'a::len word"
  7.1643 -  by (simp add: unat_def uint_mod add: nat_mod_distrib)
  7.1644 +lemma unat_mod:
  7.1645 +  \<open>unat (x mod y) = unat x mod unat y\<close>
  7.1646 +  by (simp add: uint_mod nat_mod_distrib flip: nat_uint_eq)
  7.1647  
  7.1648  
  7.1649  text \<open>Definition of \<open>unat_arith\<close> tactic\<close>
  7.1650 @@ -3015,20 +3441,16 @@
  7.1651  lemmas word_and_le2 = xtrans(3) [OF word_ao_absorbs (8) [symmetric] le_word_or2]
  7.1652  
  7.1653  lemma bl_word_not: "to_bl (NOT w) = map Not (to_bl w)"
  7.1654 -  unfolding to_bl_def word_log_defs bl_not_bin
  7.1655 -  by (simp add: word_ubin.eq_norm)
  7.1656 +  by transfer (simp add: bl_not_bin)
  7.1657  
  7.1658  lemma bl_word_xor: "to_bl (v XOR w) = map2 (\<noteq>) (to_bl v) (to_bl w)"
  7.1659 -  unfolding to_bl_def word_log_defs bl_xor_bin
  7.1660 -  by (simp add: word_ubin.eq_norm)
  7.1661 +  by transfer (simp flip: bl_xor_bin)
  7.1662  
  7.1663  lemma bl_word_or: "to_bl (v OR w) = map2 (\<or>) (to_bl v) (to_bl w)"
  7.1664 -  unfolding to_bl_def word_log_defs bl_or_bin
  7.1665 -  by (simp add: word_ubin.eq_norm)
  7.1666 +  by transfer (simp flip: bl_or_bin)
  7.1667  
  7.1668  lemma bl_word_and: "to_bl (v AND w) = map2 (\<and>) (to_bl v) (to_bl w)"
  7.1669 -  unfolding to_bl_def word_log_defs bl_and_bin
  7.1670 -  by (simp add: word_ubin.eq_norm)
  7.1671 +  by transfer (simp flip: bl_and_bin)
  7.1672  
  7.1673  lemma bin_nth_uint': "bin_nth (uint w) n \<longleftrightarrow> rev (bin_to_bl (size w) (uint w)) ! n \<and> n < size w"
  7.1674    apply (unfold word_size)
  7.1675 @@ -3040,7 +3462,7 @@
  7.1676  lemmas bin_nth_uint = bin_nth_uint' [unfolded word_size]
  7.1677  
  7.1678  lemma test_bit_bl: "w !! n \<longleftrightarrow> rev (to_bl w) ! n \<and> n < size w"
  7.1679 -  unfolding to_bl_def word_test_bit_def word_size by (rule bin_nth_uint)
  7.1680 +  by transfer (auto simp add: bin_nth_bl)
  7.1681  
  7.1682  lemma to_bl_nth: "n < size w \<Longrightarrow> to_bl w ! n = w !! (size w - Suc n)"
  7.1683    by (simp add: word_size rev_nth test_bit_bl)
  7.1684 @@ -3087,6 +3509,18 @@
  7.1685    \<open>of_bl bs = horner_sum of_bool 2 (rev bs)\<close>
  7.1686    by (rule bit_word_eqI) (simp add: bit_of_bl_iff bit_horner_sum_bit_word_iff ac_simps)
  7.1687  
  7.1688 +lemma [code abstract]:
  7.1689 +  \<open>uint (of_bl bs :: 'a word) = horner_sum of_bool 2 (take LENGTH('a::len) (rev bs))\<close>
  7.1690 +  apply (simp add: of_bl_eq flip: take_bit_horner_sum_bit_eq)
  7.1691 +  apply transfer
  7.1692 +  apply simp
  7.1693 +  done
  7.1694 +
  7.1695 +lemma [code]:
  7.1696 +  \<open>to_bl w = map (bit w) (rev [0..<LENGTH('a::len)])\<close>
  7.1697 +  for w :: \<open>'a::len word\<close>
  7.1698 +  by (simp add: to_bl_unfold rev_map)
  7.1699 +
  7.1700  definition word_reverse :: \<open>'a::len word \<Rightarrow> 'a word\<close>
  7.1701    where \<open>word_reverse w = horner_sum of_bool 2 (rev (map (bit w) [0..<LENGTH('a)]))\<close>
  7.1702  
  7.1703 @@ -3127,17 +3561,11 @@
  7.1704    by (auto simp: nth_sbintr word_test_bit_def [symmetric])
  7.1705  
  7.1706  lemma setBit_no [simp]: "setBit (numeral bin) n = word_of_int (bin_sc n True (numeral bin))"
  7.1707 -  apply (simp add: setBit_def bin_sc_eq set_bit_def)
  7.1708 -  apply transfer
  7.1709 -  apply simp
  7.1710 -  done
  7.1711 +  by transfer (simp add: bin_sc_eq)
  7.1712   
  7.1713  lemma clearBit_no [simp]:
  7.1714    "clearBit (numeral bin) n = word_of_int (bin_sc n False (numeral bin))"
  7.1715 -  apply (simp add: clearBit_def bin_sc_eq unset_bit_def)
  7.1716 -  apply transfer
  7.1717 -  apply simp
  7.1718 -  done
  7.1719 +  by transfer (simp add: bin_sc_eq)
  7.1720  
  7.1721  lemma to_bl_n1 [simp]: "to_bl (-1::'a::len word) = replicate (LENGTH('a)) True"
  7.1722    apply (rule word_bl.Abs_inverse')
  7.1723 @@ -3238,10 +3666,7 @@
  7.1724  subsection \<open>Shifting, Rotating, and Splitting Words\<close>
  7.1725  
  7.1726  lemma shiftl1_wi [simp]: "shiftl1 (word_of_int w) = word_of_int (2 * w)"
  7.1727 -  unfolding shiftl1_def
  7.1728 -  apply (simp add: word_ubin.norm_eq_iff [symmetric] word_ubin.eq_norm)
  7.1729 -  apply (simp add: mod_mult_right_eq take_bit_eq_mod)
  7.1730 -  done
  7.1731 +  by (fact shiftl1.abs_eq)
  7.1732  
  7.1733  lemma shiftl1_numeral [simp]: "shiftl1 (numeral w) = numeral (Num.Bit0 w)"
  7.1734    unfolding word_numeral_alt shiftl1_wi by simp
  7.1735 @@ -3250,57 +3675,46 @@
  7.1736    unfolding word_neg_numeral_alt shiftl1_wi by simp
  7.1737  
  7.1738  lemma shiftl1_0 [simp] : "shiftl1 0 = 0"
  7.1739 -  by (simp add: shiftl1_def)
  7.1740 +  by transfer simp
  7.1741  
  7.1742  lemma shiftl1_def_u: "shiftl1 w = word_of_int (2 * uint w)"
  7.1743 -  by (fact shiftl1_def)
  7.1744 +  by (fact shiftl1_eq)
  7.1745  
  7.1746  lemma shiftl1_def_s: "shiftl1 w = word_of_int (2 * sint w)"
  7.1747 -  by (simp add: shiftl1_def wi_hom_syms)
  7.1748 +  by (simp add: shiftl1_def_u wi_hom_syms)
  7.1749  
  7.1750  lemma shiftr1_0 [simp]: "shiftr1 0 = 0"
  7.1751 -  by (simp add: shiftr1_def)
  7.1752 +  by transfer simp
  7.1753  
  7.1754  lemma sshiftr1_0 [simp]: "sshiftr1 0 = 0"
  7.1755 -  by (simp add: sshiftr1_def)
  7.1756 +  by transfer simp
  7.1757  
  7.1758  lemma sshiftr1_n1 [simp]: "sshiftr1 (- 1) = - 1"
  7.1759 -  by (simp add: sshiftr1_def)
  7.1760 +  by transfer simp
  7.1761  
  7.1762  lemma shiftl_0 [simp]: "(0::'a::len word) << n = 0"
  7.1763 -  by (induct n) (auto simp: shiftl_def)
  7.1764 +  by transfer simp
  7.1765  
  7.1766  lemma shiftr_0 [simp]: "(0::'a::len word) >> n = 0"
  7.1767 -  by (induct n) (auto simp: shiftr_def)
  7.1768 +  by transfer simp
  7.1769  
  7.1770  lemma sshiftr_0 [simp]: "0 >>> n = 0"
  7.1771 -  by (induct n) (auto simp: sshiftr_def)
  7.1772 +  by transfer simp
  7.1773  
  7.1774  lemma sshiftr_n1 [simp]: "-1 >>> n = -1"
  7.1775 -  by (induct n) (auto simp: sshiftr_def)
  7.1776 +  by transfer simp
  7.1777  
  7.1778  lemma nth_shiftl1: "shiftl1 w !! n \<longleftrightarrow> n < size w \<and> n > 0 \<and> w !! (n - 1)"
  7.1779 -  apply (unfold shiftl1_def word_test_bit_def)
  7.1780 -  apply (simp add: nth_bintr word_ubin.eq_norm word_size)
  7.1781 -  apply (cases n)
  7.1782 -  apply (simp_all add: bit_Suc)
  7.1783 -  done
  7.1784 +  by transfer (auto simp add: bit_double_iff)
  7.1785  
  7.1786  lemma nth_shiftl': "(w << m) !! n \<longleftrightarrow> n < size w \<and> n >= m \<and> w !! (n - m)"
  7.1787    for w :: "'a::len word"
  7.1788 -  apply (unfold shiftl_def)
  7.1789 -  apply (induct m arbitrary: n)
  7.1790 -   apply (force elim!: test_bit_size)
  7.1791 -  apply (clarsimp simp add : nth_shiftl1 word_size)
  7.1792 -  apply arith
  7.1793 -  done
  7.1794 +  by transfer (auto simp add: bit_push_bit_iff)
  7.1795  
  7.1796  lemmas nth_shiftl = nth_shiftl' [unfolded word_size]
  7.1797  
  7.1798  lemma nth_shiftr1: "shiftr1 w !! n = w !! Suc n"
  7.1799 -  apply (auto simp add: shiftr1_def word_test_bit_def word_ubin.eq_norm bit_take_bit_iff bit_Suc)
  7.1800 -  apply (metis (no_types, hide_lams) add_Suc_right add_diff_cancel_left' bit_Suc diff_is_0_eq' le_Suc_ex less_imp_le linorder_not_le test_bit_bin word_test_bit_def)
  7.1801 -  done
  7.1802 +  by transfer (auto simp add: bit_take_bit_iff simp flip: bit_Suc)
  7.1803  
  7.1804  lemma nth_shiftr: "(w >> m) !! n = w !! (n + m)"
  7.1805    for w :: "'a::len word"
  7.1806 @@ -3316,79 +3730,47 @@
  7.1807  \<close>
  7.1808  
  7.1809  lemma uint_shiftr1: "uint (shiftr1 w) = bin_rest (uint w)"
  7.1810 -  apply (unfold shiftr1_def word_ubin.eq_norm bin_rest_trunc_i)
  7.1811 -  apply (subst bintr_uint [symmetric, OF order_refl])
  7.1812 -  apply (simp only : bintrunc_bintrunc_l)
  7.1813 -  apply simp
  7.1814 -  done
  7.1815 +  by transfer simp
  7.1816  
  7.1817  lemma bit_sshiftr1_iff:
  7.1818    \<open>bit (sshiftr1 w) n \<longleftrightarrow> bit w (if n = LENGTH('a) - 1 then LENGTH('a) - 1 else Suc n)\<close>
  7.1819    for w :: \<open>'a::len word\<close>
  7.1820 -  apply (cases \<open>LENGTH('a)\<close>)
  7.1821 -  apply simp
  7.1822 -  apply (simp add: sshiftr1_def bit_word_of_int_iff bit_sint_iff flip: bit_Suc)
  7.1823 -  apply transfer apply auto
  7.1824 +  apply transfer
  7.1825 +  apply (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def simp flip: bit_Suc)
  7.1826 +  using le_less_Suc_eq apply fastforce
  7.1827 +  using le_less_Suc_eq apply fastforce
  7.1828    done
  7.1829  
  7.1830  lemma bit_sshiftr_word_iff:
  7.1831    \<open>bit (w >>> m) n \<longleftrightarrow> bit w (if LENGTH('a) - m \<le> n \<and> n < LENGTH('a) then LENGTH('a) - 1 else (m + n))\<close>
  7.1832    for w :: \<open>'a::len word\<close>
  7.1833 -  apply (cases \<open>LENGTH('a)\<close>)
  7.1834 -   apply simp
  7.1835 -  apply (simp only:)
  7.1836 -  apply (induction m arbitrary: n)
  7.1837 -   apply (auto simp add: sshiftr_def bit_sshiftr1_iff not_le less_diff_conv)
  7.1838 +  apply transfer
  7.1839 +  apply (auto simp add: bit_take_bit_iff bit_drop_bit_eq bit_signed_take_bit_iff min_def not_le simp flip: bit_Suc)
  7.1840 +  using le_less_Suc_eq apply fastforce
  7.1841 +  using le_less_Suc_eq apply fastforce
  7.1842    done
  7.1843  
  7.1844  lemma nth_sshiftr1: "sshiftr1 w !! n = (if n = size w - 1 then w !! n else w !! Suc n)"
  7.1845 -  apply (unfold sshiftr1_def word_test_bit_def)
  7.1846 -  apply (simp add: nth_bintr word_ubin.eq_norm bit_Suc [symmetric] word_size)
  7.1847 -  apply (simp add: nth_bintr uint_sint)
  7.1848 -  apply (auto simp add: bin_nth_sint)
  7.1849 +  apply transfer
  7.1850 +  apply (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def simp flip: bit_Suc)
  7.1851 +  using le_less_Suc_eq apply fastforce
  7.1852 +  using le_less_Suc_eq apply fastforce
  7.1853    done
  7.1854  
  7.1855 -lemma nth_sshiftr [rule_format] :
  7.1856 -  "\<forall>n. sshiftr w m !! n =
  7.1857 +lemma nth_sshiftr :
  7.1858 +  "sshiftr w m !! n =
  7.1859      (n < size w \<and> (if n + m \<ge> size w then w !! (size w - 1) else w !! (n + m)))"
  7.1860 -  apply (unfold sshiftr_def)
  7.1861 -  apply (induct_tac m)
  7.1862 -   apply (simp add: test_bit_bl)
  7.1863 -  apply (clarsimp simp add: nth_sshiftr1 word_size)
  7.1864 -  apply safe
  7.1865 -       apply arith
  7.1866 -      apply arith
  7.1867 -     apply (erule thin_rl)
  7.1868 -     apply (case_tac n)
  7.1869 -      apply safe
  7.1870 -      apply simp
  7.1871 -     apply simp
  7.1872 -    apply (erule thin_rl)
  7.1873 -    apply (case_tac n)
  7.1874 -     apply safe
  7.1875 -     apply simp
  7.1876 -    apply simp
  7.1877 -   apply arith+
  7.1878 +  apply transfer
  7.1879 +  apply (auto simp add: bit_take_bit_iff bit_drop_bit_eq bit_signed_take_bit_iff min_def not_le ac_simps)
  7.1880 +  using le_less_Suc_eq apply fastforce
  7.1881 +  using le_less_Suc_eq apply fastforce
  7.1882    done
  7.1883  
  7.1884  lemma shiftr1_div_2: "uint (shiftr1 w) = uint w div 2"
  7.1885 -  apply (unfold shiftr1_def)
  7.1886 -  apply (rule word_uint.Abs_inverse)
  7.1887 -  apply (simp add: uints_num pos_imp_zdiv_nonneg_iff)
  7.1888 -  apply (metis uint_lt2p uint_shiftr1)
  7.1889 -  done
  7.1890 +  by (fact uint_shiftr1)
  7.1891  
  7.1892  lemma sshiftr1_div_2: "sint (sshiftr1 w) = sint w div 2"
  7.1893 -  apply (unfold sshiftr1_def)
  7.1894 -  apply (simp add: word_sbin.eq_norm)
  7.1895 -  apply (rule trans)
  7.1896 -   defer
  7.1897 -   apply (subst word_sbin.norm_Rep [symmetric])
  7.1898 -   apply (rule refl)
  7.1899 -  apply (subst word_sbin.norm_Rep [symmetric])
  7.1900 -  apply (unfold One_nat_def)
  7.1901 -  apply (rule sbintrunc_rest)
  7.1902 -  done
  7.1903 +  by transfer simp
  7.1904  
  7.1905  lemma shiftr_div_2n: "uint (shiftr w n) = uint w div 2 ^ n"
  7.1906    apply (unfold shiftr_def)
  7.1907 @@ -3398,19 +3780,17 @@
  7.1908    done
  7.1909  
  7.1910  lemma sshiftr_div_2n: "sint (sshiftr w n) = sint w div 2 ^ n"
  7.1911 -  apply (unfold sshiftr_def)
  7.1912 -  apply (induct n)
  7.1913 -   apply simp
  7.1914 -  apply (simp add: sshiftr1_div_2 mult.commute zdiv_zmult2_eq [symmetric])
  7.1915 +  apply transfer
  7.1916 +  apply (auto simp add: bit_eq_iff bit_signed_take_bit_iff bit_drop_bit_eq min_def simp flip: drop_bit_eq_div)
  7.1917    done
  7.1918  
  7.1919  lemma bit_bshiftr1_iff:
  7.1920    \<open>bit (bshiftr1 b w) n \<longleftrightarrow> b \<and> n = LENGTH('a) - 1 \<or> bit w (Suc n)\<close>
  7.1921    for w :: \<open>'a::len word\<close>
  7.1922 -  apply (cases \<open>LENGTH('a)\<close>)
  7.1923 -  apply simp
  7.1924 -  apply (simp add: bshiftr1_def bit_of_bl_iff nth_append not_less rev_nth nth_butlast nth_to_bl)
  7.1925 -  apply (use bit_imp_le_length in fastforce)
  7.1926 +  apply transfer
  7.1927 +  apply (simp add: bit_take_bit_iff flip: bit_Suc)
  7.1928 +    apply (subst disjunctive_add)
  7.1929 +   apply (auto simp add: bit_take_bit_iff bit_or_iff bit_exp_iff simp flip: bit_Suc)
  7.1930    done
  7.1931  
  7.1932  
  7.1933 @@ -3418,10 +3798,10 @@
  7.1934  
  7.1935  lemma bshiftr1_numeral [simp]:
  7.1936    \<open>bshiftr1 b (numeral w :: 'a word) = of_bl (b # butlast (bin_to_bl LENGTH('a::len) (numeral w)))\<close>
  7.1937 -  by (simp add: bshiftr1_def)
  7.1938 +  by (simp add: bshiftr1_eq)
  7.1939  
  7.1940  lemma bshiftr1_bl: "to_bl (bshiftr1 b w) = b # butlast (to_bl w)"
  7.1941 -  unfolding bshiftr1_def by (rule word_bl.Abs_inverse) simp
  7.1942 +  unfolding bshiftr1_eq by (rule word_bl.Abs_inverse) simp
  7.1943  
  7.1944  lemma shiftl1_of_bl: "shiftl1 (of_bl bl) = of_bl (bl @ [False])"
  7.1945    by (simp add: of_bl_def bl_to_bin_append)
  7.1946 @@ -3445,9 +3825,13 @@
  7.1947    by (simp add: shiftl1_bl word_rep_drop drop_Suc del: drop_append)
  7.1948  
  7.1949  lemma shiftr1_bl: "shiftr1 w = of_bl (butlast (to_bl w))"
  7.1950 -  apply (unfold shiftr1_def uint_bl of_bl_def)
  7.1951 -  apply (simp add: butlast_rest_bin word_size)
  7.1952 -  apply (simp add: bin_rest_trunc [symmetric, unfolded One_nat_def])
  7.1953 +  apply (rule bit_word_eqI)
  7.1954 +  apply (simp add: bit_shiftr1_iff bit_of_bl_iff)
  7.1955 +  apply auto
  7.1956 +     apply (metis bin_nth_of_bl bin_rest_bl_to_bin bit_Suc test_bit_bin test_bit_word_eq to_bl_to_bin)
  7.1957 +  using bit_Suc nat_less_le not_bit_length apply blast
  7.1958 +   apply (simp add: bit_imp_le_length less_diff_conv)
  7.1959 +  apply (metis bin_nth_of_bl bin_rest_bl_to_bin bit_Suc butlast_bin_rest size_bin_to_bl test_bit_bin test_bit_word_eq to_bl_to_bin word_bl_Rep')
  7.1960    done
  7.1961  
  7.1962  lemma bl_shiftr1: "to_bl (shiftr1 w) = False # butlast (to_bl w)"
  7.1963 @@ -3480,20 +3864,16 @@
  7.1964  
  7.1965  lemma bl_sshiftr1: "to_bl (sshiftr1 w) = hd (to_bl w) # butlast (to_bl w)"
  7.1966    for w :: "'a::len word"
  7.1967 -  apply (unfold sshiftr1_def uint_bl word_size)
  7.1968 -  apply (simp add: butlast_rest_bin word_ubin.eq_norm)
  7.1969 -  apply (simp add: sint_uint)
  7.1970 -  apply (rule nth_equalityI)
  7.1971 -   apply clarsimp
  7.1972 -  apply clarsimp
  7.1973 -  apply (case_tac i)
  7.1974 -   apply (simp_all add: hd_conv_nth length_0_conv [symmetric]
  7.1975 -      nth_bin_to_bl bit_Suc [symmetric] nth_sbintr)
  7.1976 -   apply force
  7.1977 -  apply (rule impI)
  7.1978 -  apply (rule_tac f = "bin_nth (uint w)" in arg_cong)
  7.1979 -  apply simp
  7.1980 -  done
  7.1981 +proof (rule nth_equalityI)
  7.1982 +  fix n
  7.1983 +  assume \<open>n < length (to_bl (sshiftr1 w))\<close>
  7.1984 +  then have \<open>n < LENGTH('a)\<close>
  7.1985 +    by simp
  7.1986 +  then show \<open>to_bl (sshiftr1 w) ! n \<longleftrightarrow> (hd (to_bl w) # butlast (to_bl w)) ! n\<close>
  7.1987 +    apply (cases n)
  7.1988 +     apply (simp_all add: to_bl_nth word_size hd_conv_nth test_bit_eq_bit bit_sshiftr1_iff nth_butlast Suc_diff_Suc nth_to_bl)
  7.1989 +    done
  7.1990 +qed simp
  7.1991  
  7.1992  lemma drop_shiftr: "drop n (to_bl (w >> n)) = take (size w - n) (to_bl w)"
  7.1993    for w :: "'a::len word"
  7.1994 @@ -3507,7 +3887,7 @@
  7.1995  
  7.1996  lemma drop_sshiftr: "drop n (to_bl (w >>> n)) = take (size w - n) (to_bl w)"
  7.1997    for w :: "'a::len word"
  7.1998 -  apply (unfold sshiftr_def)
  7.1999 +  apply (unfold sshiftr_eq)
  7.2000    apply (induct n)
  7.2001     prefer 2
  7.2002     apply (simp add: drop_Suc bl_sshiftr1 butlast_drop [symmetric])
  7.2003 @@ -3528,7 +3908,7 @@
  7.2004    "n \<le> size w \<longrightarrow> hd (to_bl (w >>> n)) = hd (to_bl w) \<and>
  7.2005      take n (to_bl (w >>> n)) = replicate n (hd (to_bl w))"
  7.2006    for w :: "'a::len word"
  7.2007 -  apply (unfold sshiftr_def)
  7.2008 +  apply (unfold sshiftr_eq)
  7.2009    apply (induct n)
  7.2010     prefer 2
  7.2011     apply (simp add: bl_sshiftr1)
  7.2012 @@ -3577,7 +3957,7 @@
  7.2013  
  7.2014  lemma shiftl1_2t: "shiftl1 w = 2 * w"
  7.2015    for w :: "'a::len word"
  7.2016 -  by (simp add: shiftl1_def wi_hom_mult [symmetric])
  7.2017 +  by (simp add: shiftl1_eq wi_hom_mult [symmetric])
  7.2018  
  7.2019  lemma shiftl1_p: "shiftl1 w = w + w"
  7.2020    for w :: "'a::len word"
  7.2021 @@ -3590,12 +3970,12 @@
  7.2022  lemma shiftr1_bintr [simp]:
  7.2023    "(shiftr1 (numeral w) :: 'a::len word) =
  7.2024      word_of_int (bin_rest (bintrunc (LENGTH('a)) (numeral w)))"
  7.2025 -  unfolding shiftr1_def word_numeral_alt by (simp add: word_ubin.eq_norm)
  7.2026 +  unfolding shiftr1_eq word_numeral_alt by (simp add: word_ubin.eq_norm)
  7.2027  
  7.2028  lemma sshiftr1_sbintr [simp]:
  7.2029    "(sshiftr1 (numeral w) :: 'a::len word) =
  7.2030      word_of_int (bin_rest (sbintrunc (LENGTH('a) - 1) (numeral w)))"
  7.2031 -  unfolding sshiftr1_def word_numeral_alt by (simp add: word_sbin.eq_norm)
  7.2032 +  unfolding sshiftr1_eq word_numeral_alt by (simp add: word_sbin.eq_norm)
  7.2033  
  7.2034  text \<open>TODO: rules for \<^term>\<open>- (numeral n)\<close>\<close>
  7.2035  
  7.2036 @@ -3619,7 +3999,7 @@
  7.2037  lemma shiftr1_bl_of:
  7.2038    "length bl \<le> LENGTH('a) \<Longrightarrow>
  7.2039      shiftr1 (of_bl bl::'a::len word) = of_bl (butlast bl)"
  7.2040 -  by (clarsimp simp: shiftr1_def of_bl_def butlast_rest_bl2bin word_ubin.eq_norm trunc_bl2bin)
  7.2041 +  by (clarsimp simp: shiftr1_eq of_bl_def butlast_rest_bl2bin word_ubin.eq_norm trunc_bl2bin)
  7.2042  
  7.2043  lemma shiftr_bl_of:
  7.2044    "length bl \<le> LENGTH('a) \<Longrightarrow>
  7.2045 @@ -3698,17 +4078,17 @@
  7.2046    \<open>- 1 = (Bit_Operations.mask LENGTH('a) :: 'a::len word)\<close>
  7.2047    by (rule bit_eqI) (simp add: bit_exp_iff bit_mask_iff exp_eq_zero_iff)
  7.2048    
  7.2049 -lemma mask_eq_mask:
  7.2050 +lemma mask_eq_mask [code]:
  7.2051    \<open>mask = Bit_Operations.mask\<close>
  7.2052 -  by (simp add: fun_eq_iff mask_eq_exp_minus_1 mask_def shiftl_word_eq push_bit_eq_mult)
  7.2053 -
  7.2054 -lemma mask_eq:
  7.2055 +  by (rule ext, transfer) simp
  7.2056 +
  7.2057 +lemma mask_eq_decr_exp:
  7.2058    \<open>mask n = 2 ^ n - 1\<close>
  7.2059    by (simp add: mask_eq_mask mask_eq_exp_minus_1)
  7.2060  
  7.2061  lemma mask_Suc_rec:
  7.2062    \<open>mask (Suc n) = 2 * mask n + 1\<close>
  7.2063 -  by (simp add: mask_eq)
  7.2064 +  by (simp add: mask_eq_mask mask_eq_exp_minus_1)
  7.2065  
  7.2066  context
  7.2067  begin
  7.2068 @@ -3782,13 +4162,10 @@
  7.2069    done
  7.2070  
  7.2071  lemma and_mask_dvd_nat: "2 ^ n dvd unat w \<longleftrightarrow> w AND mask n = 0"
  7.2072 -  apply (unfold unat_def)
  7.2073 -  apply (rule trans [OF _ and_mask_dvd])
  7.2074 -  apply (unfold dvd_def)
  7.2075 -  apply auto
  7.2076 -   apply (drule uint_ge_0 [THEN nat_int.Abs_inverse' [simplified], symmetric])
  7.2077 -   apply simp
  7.2078 -  apply (simp add: nat_mult_distrib nat_power_eq)
  7.2079 +  apply (simp flip: and_mask_dvd)
  7.2080 +  apply transfer
  7.2081 +  using dvd_nat_abs_iff [of _ \<open>take_bit LENGTH('a) k\<close> for k]
  7.2082 +  apply simp
  7.2083    done
  7.2084  
  7.2085  lemma word_2p_lem: "n < size w \<Longrightarrow> w < 2 ^ n = (uint w < 2 ^ n)"
  7.2086 @@ -3839,7 +4216,7 @@
  7.2087    by (auto simp: and_mask_wi' word_of_int_power_hom word.abs_eq_iff bintrunc_mod2p mod_simps)
  7.2088  
  7.2089  lemma mask_full [simp]: "mask LENGTH('a) = (- 1 :: 'a::len word)"
  7.2090 -  by (simp add: mask_def word_size shiftl_zero_size)
  7.2091 +  by transfer (simp add: take_bit_minus_one_eq_mask)
  7.2092  
  7.2093  
  7.2094  subsubsection \<open>Slices\<close>
  7.2095 @@ -4068,8 +4445,7 @@
  7.2096     apply (auto simp: takefill_alt wsst_TYs)
  7.2097    done
  7.2098  
  7.2099 -(* FIXME: should this also be [OF refl] ? *)
  7.2100 -lemma cast_down_rev:
  7.2101 +lemma cast_down_rev [OF refl]:
  7.2102    "uc = ucast \<Longrightarrow> source_size uc = target_size uc + n \<Longrightarrow> uc w = revcast (w << n)"
  7.2103    for w :: "'a::len word"
  7.2104    apply (unfold shiftl_rev)
  7.2105 @@ -4152,11 +4528,11 @@
  7.2106  lemmas word_rsplit_no_cl [simp] = word_rsplit_no
  7.2107    [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]]
  7.2108  
  7.2109 -lemma test_bit_cat:
  7.2110 +lemma test_bit_cat [OF refl]:
  7.2111    "wc = word_cat a b \<Longrightarrow> wc !! n = (n < size wc \<and>
  7.2112      (if n < size b then b !! n else a !! (n - size b)))"
  7.2113 -  apply (auto simp: word_cat_bin' test_bit_bin word_ubin.eq_norm nth_bintr bin_nth_cat word_size)
  7.2114 -  apply (erule bin_nth_uint_imp)
  7.2115 +  apply (simp add: word_size not_less; transfer)
  7.2116 +       apply (auto simp add: bit_concat_bit_iff bit_take_bit_iff)
  7.2117    done
  7.2118  
  7.2119  lemma word_cat_bl: "word_cat a b = of_bl (to_bl a @ to_bl b)"
  7.2120 @@ -4194,7 +4570,7 @@
  7.2121    apply safe
  7.2122     defer
  7.2123     apply (clarsimp split: prod.splits)
  7.2124 -  apply (metis of_bl_drop' ucast_bl ucast_def word_size word_size_bl)
  7.2125 +   apply (metis of_bl.abs_eq size_word.rep_eq to_bl_to_bin trunc_bl2bin word_size_bl word_ubin.eq_norm word_uint.Rep_inverse)
  7.2126     apply hypsubst_thin
  7.2127     apply (drule word_ubin.norm_Rep [THEN ssubst])
  7.2128     apply (simp add: of_bl_def bl2bin_drop word_size
  7.2129 @@ -4204,7 +4580,7 @@
  7.2130     apply (simp_all add: not_le)
  7.2131    defer
  7.2132     apply (simp add: drop_bit_eq_div lt2p_lem)
  7.2133 -  apply (simp add : of_bl_def to_bl_def)
  7.2134 +  apply (simp add: to_bl_eq)
  7.2135    apply (subst bin_to_bl_drop_bit [symmetric])
  7.2136     apply (subst diff_add)
  7.2137      apply (simp_all add: take_bit_drop_bit)
  7.2138 @@ -4268,15 +4644,15 @@
  7.2139        result to the length given by the result type\<close>
  7.2140  
  7.2141  lemma word_cat_id: "word_cat a b = b"
  7.2142 -  by (simp add: word_cat_bin' word_ubin.inverse_norm)
  7.2143 +  by transfer simp
  7.2144  
  7.2145  \<comment> \<open>limited hom result\<close>
  7.2146  lemma word_cat_hom:
  7.2147    "LENGTH('a::len) \<le> LENGTH('b::len) + LENGTH('c::len) \<Longrightarrow>
  7.2148      (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) =
  7.2149      word_of_int (bin_cat w (size b) (uint b))"
  7.2150 -  by (auto simp: word_cat_def word_size word_ubin.norm_eq_iff [symmetric]
  7.2151 -      word_ubin.eq_norm bintr_cat min.absorb1)
  7.2152 +  apply transfer
  7.2153 +  using bintr_cat by auto
  7.2154  
  7.2155  lemma word_cat_split_alt: "size w \<le> size u + size v \<Longrightarrow> word_split w = (u, v) \<Longrightarrow> word_cat u v = w"
  7.2156    apply (rule word_eqI)
  7.2157 @@ -4495,264 +4871,10 @@
  7.2158  
  7.2159  subsection \<open>Rotation\<close>
  7.2160  
  7.2161 -lemmas rotater_0' [simp] = rotater_def [where n = "0", simplified]
  7.2162 -
  7.2163 -lemma bit_word_rotl_iff:
  7.2164 -  \<open>bit (word_rotl m w) n \<longleftrightarrow>
  7.2165 -    n < LENGTH('a) \<and> bit w ((n + (LENGTH('a) - m mod LENGTH('a))) mod LENGTH('a))\<close>
  7.2166 -  for w :: \<open>'a::len word\<close>
  7.2167 -proof (cases \<open>n < LENGTH('a)\<close>)
  7.2168 -  case False
  7.2169 -  then show ?thesis
  7.2170 -    by (auto dest: bit_imp_le_length)
  7.2171 -next
  7.2172 -  case True
  7.2173 -  define k where \<open>k = int n - int m\<close>
  7.2174 -  then have k: \<open>int n = k + int m\<close>
  7.2175 -    by simp
  7.2176 -  define l where \<open>l = int LENGTH('a)\<close>
  7.2177 -  then have l: \<open>int LENGTH('a) = l\<close> \<open>l > 0\<close>
  7.2178 -    by simp_all
  7.2179 -  have *: \<open>int (m - n) = int m - int n\<close> if \<open>n \<le> m\<close> for n m
  7.2180 -    using that by (simp add: int_minus)
  7.2181 -  from \<open>l > 0\<close> have \<open>l = 1 + (k mod l + ((- 1 - k) mod l))\<close>
  7.2182 -    using minus_mod_int_eq [of l \<open>k + 1\<close>] by (simp add: algebra_simps)
  7.2183 -  then have \<open>int (LENGTH('a) - Suc ((m + LENGTH('a) - Suc n) mod LENGTH('a))) =
  7.2184 -    int ((n + LENGTH('a) - m mod LENGTH('a)) mod LENGTH('a))\<close>
  7.2185 -    by (simp add: * k l zmod_int Suc_leI trans_le_add2 algebra_simps mod_simps \<open>n < LENGTH('a)\<close>)
  7.2186 -  then have \<open>LENGTH('a) - Suc ((m + LENGTH('a) - Suc n) mod LENGTH('a)) =
  7.2187 -    (n + LENGTH('a) - m mod LENGTH('a)) mod LENGTH('a)\<close>
  7.2188 -    by simp
  7.2189 -  with True show ?thesis
  7.2190 -    by (simp add: word_rotl_def bit_of_bl_iff rev_nth nth_rotate nth_to_bl)
  7.2191 -qed
  7.2192 -
  7.2193 -lemmas word_rot_defs = word_roti_def word_rotr_def word_rotl_def
  7.2194 -
  7.2195 -lemma rotate_eq_mod: "m mod length xs = n mod length xs \<Longrightarrow> rotate m xs = rotate n xs"
  7.2196 -  apply (rule box_equals)
  7.2197 -    defer
  7.2198 -    apply (rule rotate_conv_mod [symmetric])+
  7.2199 -  apply simp
  7.2200 -  done
  7.2201 -
  7.2202 -lemmas rotate_eqs =
  7.2203 -  trans [OF rotate0 [THEN fun_cong] id_apply]
  7.2204 -  rotate_rotate [symmetric]
  7.2205 -  rotate_id
  7.2206 -  rotate_conv_mod
  7.2207 -  rotate_eq_mod
  7.2208 -
  7.2209 -
  7.2210 -subsubsection \<open>Rotation of list to right\<close>
  7.2211 -
  7.2212 -lemma rotate1_rl': "rotater1 (l @ [a]) = a # l"
  7.2213 -  by (cases l) (auto simp: rotater1_def)
  7.2214 -
  7.2215 -lemma rotate1_rl [simp] : "rotater1 (rotate1 l) = l"
  7.2216 -  apply (unfold rotater1_def)
  7.2217 -  apply (cases "l")
  7.2218 -   apply (case_tac [2] "list")
  7.2219 -    apply auto
  7.2220 -  done
  7.2221 -
  7.2222 -lemma rotate1_lr [simp] : "rotate1 (rotater1 l) = l"
  7.2223 -  by (cases l) (auto simp: rotater1_def)
  7.2224 -
  7.2225 -lemma rotater1_rev': "rotater1 (rev xs) = rev (rotate1 xs)"
  7.2226 -  by (cases "xs") (simp add: rotater1_def, simp add: rotate1_rl')
  7.2227 -
  7.2228 -lemma rotater_rev': "rotater n (rev xs) = rev (rotate n xs)"
  7.2229 -  by (induct n) (auto simp: rotater_def intro: rotater1_rev')
  7.2230 -
  7.2231 -lemma rotater_rev: "rotater n ys = rev (rotate n (rev ys))"
  7.2232 -  using rotater_rev' [where xs = "rev ys"] by simp
  7.2233 -
  7.2234 -lemma rotater_drop_take:
  7.2235 -  "rotater n xs =
  7.2236 -    drop (length xs - n mod length xs) xs @
  7.2237 -    take (length xs - n mod length xs) xs"
  7.2238 -  by (auto simp: rotater_rev rotate_drop_take rev_take rev_drop)
  7.2239 -
  7.2240 -lemma rotater_Suc [simp]: "rotater (Suc n) xs = rotater1 (rotater n xs)"
  7.2241 -  unfolding rotater_def by auto
  7.2242 -
  7.2243 -lemma nth_rotater:
  7.2244 -  \<open>rotater m xs ! n = xs ! ((n + (length xs - m mod length xs)) mod length xs)\<close> if \<open>n < length xs\<close>
  7.2245 -  using that by (simp add: rotater_drop_take nth_append not_less less_diff_conv ac_simps le_mod_geq)
  7.2246 -
  7.2247 -lemma nth_rotater1:
  7.2248 -  \<open>rotater1 xs ! n = xs ! ((n + (length xs - 1)) mod length xs)\<close> if \<open>n < length xs\<close>
  7.2249 -  using that nth_rotater [of n xs 1] by simp
  7.2250 -
  7.2251 -lemma rotate_inv_plus [rule_format]:
  7.2252 -  "\<forall>k. k = m + n \<longrightarrow> rotater k (rotate n xs) = rotater m xs \<and>
  7.2253 -    rotate k (rotater n xs) = rotate m xs \<and>
  7.2254 -    rotater n (rotate k xs) = rotate m xs \<and>
  7.2255 -    rotate n (rotater k xs) = rotater m xs"
  7.2256 -  by (induct n) (auto simp: rotater_def rotate_def intro: funpow_swap1 [THEN trans])
  7.2257 -
  7.2258 -lemmas rotate_inv_rel = le_add_diff_inverse2 [symmetric, THEN rotate_inv_plus]
  7.2259 -
  7.2260 -lemmas rotate_inv_eq = order_refl [THEN rotate_inv_rel, simplified]
  7.2261 -
  7.2262 -lemmas rotate_lr [simp] = rotate_inv_eq [THEN conjunct1]
  7.2263 -lemmas rotate_rl [simp] = rotate_inv_eq [THEN conjunct2, THEN conjunct1]
  7.2264 -
  7.2265 -lemma rotate_gal: "rotater n xs = ys \<longleftrightarrow> rotate n ys = xs"
  7.2266 -  by auto
  7.2267 -
  7.2268 -lemma rotate_gal': "ys = rotater n xs \<longleftrightarrow> xs = rotate n ys"
  7.2269 -  by auto
  7.2270 -
  7.2271 -lemma length_rotater [simp]: "length (rotater n xs) = length xs"
  7.2272 -  by (simp add : rotater_rev)
  7.2273 -
  7.2274 -lemma bit_word_rotr_iff:
  7.2275 -  \<open>bit (word_rotr m w) n \<longleftrightarrow>
  7.2276 -    n < LENGTH('a) \<and> bit w ((n + m) mod LENGTH('a))\<close>
  7.2277 -  for w :: \<open>'a::len word\<close>
  7.2278 -proof (cases \<open>n < LENGTH('a)\<close>)
  7.2279 -  case False
  7.2280 -  then show ?thesis
  7.2281 -    by (auto dest: bit_imp_le_length)
  7.2282 -next
  7.2283 -  case True
  7.2284 -  define k where \<open>k = int n + int m\<close>
  7.2285 -  then have k: \<open>int n = k - int m\<close>
  7.2286 -    by simp
  7.2287 -  define l where \<open>l = int LENGTH('a)\<close>
  7.2288 -  then have l: \<open>int LENGTH('a) = l\<close> \<open>l > 0\<close>
  7.2289 -    by simp_all
  7.2290 -  have *: \<open>int (m - n) = int m - int n\<close> if \<open>n \<le> m\<close> for n m
  7.2291 -    using that by (simp add: int_minus)
  7.2292 -  have \<open>int ((LENGTH('a)
  7.2293 -    - Suc ((LENGTH('a) + LENGTH('a) - Suc (n + m mod LENGTH('a))) mod LENGTH('a)))) =
  7.2294 -    int ((n + m) mod LENGTH('a))\<close>
  7.2295 -    using True
  7.2296 -    apply (simp add: l * zmod_int Suc_leI add_strict_mono)
  7.2297 -    apply (subst mod_diff_left_eq [symmetric])
  7.2298 -    apply simp
  7.2299 -    using l minus_mod_int_eq [of l \<open>int n + int m mod l + 1\<close>] apply simp
  7.2300 -    apply (simp add: mod_simps)
  7.2301 -    done
  7.2302 -  then have \<open>(LENGTH('a)
  7.2303 -    - Suc ((LENGTH('a) + LENGTH('a) - Suc (n + m mod LENGTH('a))) mod LENGTH('a))) =
  7.2304 -    ((n + m) mod LENGTH('a))\<close>
  7.2305 -    by simp
  7.2306 -  with True show ?thesis
  7.2307 -    by (simp add: word_rotr_def bit_of_bl_iff rev_nth nth_rotater nth_to_bl)
  7.2308 -qed
  7.2309 -
  7.2310 -lemma bit_word_roti_iff:
  7.2311 -  \<open>bit (word_roti k w) n \<longleftrightarrow>
  7.2312 -    n < LENGTH('a) \<and> bit w (nat ((int n + k) mod int LENGTH('a)))\<close>
  7.2313 -  for w :: \<open>'a::len word\<close>
  7.2314 -proof (cases \<open>k \<ge> 0\<close>)
  7.2315 -  case True
  7.2316 -  moreover define m where \<open>m = nat k\<close>
  7.2317 -  ultimately have \<open>k = int m\<close>
  7.2318 -    by simp
  7.2319 -  then show ?thesis
  7.2320 -    by (simp add: word_roti_def bit_word_rotr_iff nat_mod_distrib nat_add_distrib)
  7.2321 -next
  7.2322 -  have *: \<open>int (m - n) = int m - int n\<close> if \<open>n \<le> m\<close> for n m
  7.2323 -    using that by (simp add: int_minus)
  7.2324 -  case False
  7.2325 -  moreover define m where \<open>m = nat (- k)\<close>
  7.2326 -  ultimately have \<open>k = - int m\<close> \<open>k < 0\<close>
  7.2327 -    by simp_all
  7.2328 -  moreover have \<open>(int n - int m) mod int LENGTH('a) =
  7.2329 -    int ((n + LENGTH('a) - m mod LENGTH('a)) mod LENGTH('a))\<close>
  7.2330 -    apply (simp add: zmod_int * trans_le_add2 mod_simps)
  7.2331 -    apply (metis mod_add_self2 mod_diff_cong)
  7.2332 -    done
  7.2333 -  ultimately show ?thesis
  7.2334 -    by (simp add: word_roti_def bit_word_rotl_iff nat_mod_distrib)
  7.2335 -qed
  7.2336 -
  7.2337 -lemma restrict_to_left: "x = y \<Longrightarrow> x = z \<longleftrightarrow> y = z"
  7.2338 -  by simp
  7.2339 -
  7.2340 -lemmas rrs0 = rotate_eqs [THEN restrict_to_left,
  7.2341 -  simplified rotate_gal [symmetric] rotate_gal' [symmetric]]
  7.2342 -lemmas rrs1 = rrs0 [THEN refl [THEN rev_iffD1]]
  7.2343 -lemmas rotater_eqs = rrs1 [simplified length_rotater]
  7.2344 -lemmas rotater_0 = rotater_eqs (1)
  7.2345 -lemmas rotater_add = rotater_eqs (2)
  7.2346 -
  7.2347 -
  7.2348 -subsubsection \<open>map, map2, commuting with rotate(r)\<close>
  7.2349 -
  7.2350 -lemma butlast_map: "xs \<noteq> [] \<Longrightarrow> butlast (map f xs) = map f (butlast xs)"
  7.2351 -  by (induct xs) auto
  7.2352 -
  7.2353 -lemma rotater1_map: "rotater1 (map f xs) = map f (rotater1 xs)"
  7.2354 -  by (cases xs) (auto simp: rotater1_def last_map butlast_map)
  7.2355 -
  7.2356 -lemma rotater_map: "rotater n (map f xs) = map f (rotater n xs)"
  7.2357 -  by (induct n) (auto simp: rotater_def rotater1_map)
  7.2358 -
  7.2359 -lemma but_last_zip [rule_format] :
  7.2360 -  "\<forall>ys. length xs = length ys \<longrightarrow> xs \<noteq> [] \<longrightarrow>
  7.2361 -    last (zip xs ys) = (last xs, last ys) \<and>
  7.2362 -    butlast (zip xs ys) = zip (butlast xs) (butlast ys)"
  7.2363 -  apply (induct xs)
  7.2364 -   apply auto
  7.2365 -     apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
  7.2366 -  done
  7.2367 -
  7.2368 -lemma but_last_map2 [rule_format] :
  7.2369 -  "\<forall>ys. length xs = length ys \<longrightarrow> xs \<noteq> [] \<longrightarrow>
  7.2370 -    last (map2 f xs ys) = f (last xs) (last ys) \<and>
  7.2371 -    butlast (map2 f xs ys) = map2 f (butlast xs) (butlast ys)"
  7.2372 -  apply (induct xs)
  7.2373 -   apply auto
  7.2374 -     apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
  7.2375 -  done
  7.2376 -
  7.2377 -lemma rotater1_zip:
  7.2378 -  "length xs = length ys \<Longrightarrow>
  7.2379 -    rotater1 (zip xs ys) = zip (rotater1 xs) (rotater1 ys)"
  7.2380 -  apply (unfold rotater1_def)
  7.2381 -  apply (cases xs)
  7.2382 -   apply auto
  7.2383 -   apply ((case_tac ys, auto simp: neq_Nil_conv but_last_zip)[1])+
  7.2384 -  done
  7.2385 -
  7.2386 -lemma rotater1_map2:
  7.2387 -  "length xs = length ys \<Longrightarrow>
  7.2388 -    rotater1 (map2 f xs ys) = map2 f (rotater1 xs) (rotater1 ys)"
  7.2389 -  by (simp add: rotater1_map rotater1_zip)
  7.2390 -
  7.2391 -lemmas lrth =
  7.2392 -  box_equals [OF asm_rl length_rotater [symmetric]
  7.2393 -                 length_rotater [symmetric],
  7.2394 -              THEN rotater1_map2]
  7.2395 -
  7.2396 -lemma rotater_map2:
  7.2397 -  "length xs = length ys \<Longrightarrow>
  7.2398 -    rotater n (map2 f xs ys) = map2 f (rotater n xs) (rotater n ys)"
  7.2399 -  by (induct n) (auto intro!: lrth)
  7.2400 -
  7.2401 -lemma rotate1_map2:
  7.2402 -  "length xs = length ys \<Longrightarrow>
  7.2403 -    rotate1 (map2 f xs ys) = map2 f (rotate1 xs) (rotate1 ys)"
  7.2404 -  by (cases xs; cases ys) auto
  7.2405 -
  7.2406 -lemmas lth = box_equals [OF asm_rl length_rotate [symmetric]
  7.2407 -  length_rotate [symmetric], THEN rotate1_map2]
  7.2408 -
  7.2409 -lemma rotate_map2:
  7.2410 -  "length xs = length ys \<Longrightarrow>
  7.2411 -    rotate n (map2 f xs ys) = map2 f (rotate n xs) (rotate n ys)"
  7.2412 -  by (induct n) (auto intro!: lth)
  7.2413 -
  7.2414 -
  7.2415 -\<comment> \<open>corresponding equalities for word rotation\<close>
  7.2416 +lemmas word_rot_defs = word_roti_eq_word_rotr_word_rotl word_rotr_eq word_rotl_eq
  7.2417  
  7.2418  lemma to_bl_rotl: "to_bl (word_rotl n w) = rotate n (to_bl w)"
  7.2419 -  by (simp add: word_bl.Abs_inverse' word_rotl_def)
  7.2420 +  by (simp add: word_rotl_eq to_bl_use_of_bl)
  7.2421  
  7.2422  lemmas blrs0 = rotate_eqs [THEN to_bl_rotl [THEN trans]]
  7.2423  
  7.2424 @@ -4760,7 +4882,7 @@
  7.2425    blrs0 [simplified word_bl_Rep' word_bl.Rep_inject to_bl_rotl [symmetric]]
  7.2426  
  7.2427  lemma to_bl_rotr: "to_bl (word_rotr n w) = rotater n (to_bl w)"
  7.2428 -  by (simp add: word_bl.Abs_inverse' word_rotr_def)
  7.2429 +  by (simp add: word_rotr_eq to_bl_use_of_bl)
  7.2430  
  7.2431  lemmas brrs0 = rotater_eqs [THEN to_bl_rotr [THEN trans]]
  7.2432  
  7.2433 @@ -4782,7 +4904,7 @@
  7.2434    by (simp only: word_bl.Rep_inject [symmetric] to_bl_word_rev to_bl_rotr to_bl_rotl rotater_rev)
  7.2435  
  7.2436  lemma word_roti_0 [simp]: "word_roti 0 w = w"
  7.2437 -  by (auto simp: word_rot_defs)
  7.2438 +  by transfer simp
  7.2439  
  7.2440  lemmas abl_cong = arg_cong [where f = "of_bl"]
  7.2441  
  7.2442 @@ -4819,48 +4941,7 @@
  7.2443  
  7.2444  lemma word_roti_conv_mod':
  7.2445    "word_roti n w = word_roti (n mod int (size w)) w"
  7.2446 -proof (cases "size w = 0")
  7.2447 -  case True
  7.2448 -  then show ?thesis
  7.2449 -    by simp
  7.2450 -next
  7.2451 -  case False
  7.2452 -  then have [simp]: "l mod int (size w) \<ge> 0" for l
  7.2453 -    by simp
  7.2454 -  then have *: "word_roti (n mod int (size w)) w = word_rotr (nat (n mod int (size w))) w"
  7.2455 -    by (simp add: word_roti_def)
  7.2456 -  show ?thesis
  7.2457 -  proof (cases "n \<ge> 0")
  7.2458 -    case True
  7.2459 -    then show ?thesis
  7.2460 -      apply (auto simp add: not_le *)
  7.2461 -      apply (auto simp add: word_rot_defs)
  7.2462 -      apply (safe intro!: abl_cong)
  7.2463 -      apply (rule rotater_eqs)
  7.2464 -      apply (simp add: word_size nat_mod_distrib)
  7.2465 -      done
  7.2466 -  next
  7.2467 -    case False
  7.2468 -    moreover define k where "k = - n"
  7.2469 -    ultimately have n: "n = - k"
  7.2470 -      by simp_all
  7.2471 -    from False show ?thesis
  7.2472 -      apply (auto simp add: not_le *)
  7.2473 -      apply (auto simp add: word_rot_defs)
  7.2474 -      apply (simp add: n)
  7.2475 -      apply (safe intro!: abl_cong)
  7.2476 -      apply (simp add: rotater_add [symmetric] rotate_gal [symmetric])
  7.2477 -      apply (rule rotater_eqs)
  7.2478 -      apply (simp add: word_size [symmetric, of w])
  7.2479 -      apply (rule of_nat_eq_0_iff [THEN iffD1])
  7.2480 -      apply (auto simp add: nat_add_distrib [symmetric] mod_eq_0_iff_dvd)
  7.2481 -      using dvd_nat_abs_iff [of "size w" "- k mod int (size w) + k"]
  7.2482 -      apply (simp add: algebra_simps)
  7.2483 -      apply (simp add: word_size)
  7.2484 -      apply (metis dvd_eq_mod_eq_0 eq_neg_iff_add_eq_0 k_def mod_0 mod_add_right_eq n)
  7.2485 -      done
  7.2486 -  qed
  7.2487 -qed
  7.2488 +  by transfer simp
  7.2489  
  7.2490  lemmas word_roti_conv_mod = word_roti_conv_mod' [unfolded word_size]
  7.2491  
  7.2492 @@ -4910,7 +4991,7 @@
  7.2493  lemma bl_word_roti_dt':
  7.2494    "n = nat ((- i) mod int (size (w :: 'a::len word))) \<Longrightarrow>
  7.2495      to_bl (word_roti i w) = drop n (to_bl w) @ take n (to_bl w)"
  7.2496 -  apply (unfold word_roti_def)
  7.2497 +  apply (unfold word_roti_eq_word_rotr_word_rotl)
  7.2498    apply (simp add: bl_word_rotl_dt bl_word_rotr_dt word_size)
  7.2499    apply safe
  7.2500     apply (simp add: zmod_zminus1_eq_if)
  7.2501 @@ -4932,7 +5013,7 @@
  7.2502    by (simp add: word_rotr_dt word_rotl_dt replicate_add [symmetric])
  7.2503  
  7.2504  lemma word_roti_0' [simp] : "word_roti n 0 = 0"
  7.2505 -  by (auto simp: word_roti_def)
  7.2506 +  by transfer simp
  7.2507  
  7.2508  lemmas word_rotr_dt_no_bin' [simp] =
  7.2509    word_rotr_dt [where w="numeral w", unfolded to_bl_numeral] for w
  7.2510 @@ -4942,7 +5023,7 @@
  7.2511    word_rotl_dt [where w="numeral w", unfolded to_bl_numeral] for w
  7.2512    (* FIXME: negative numerals, 0 and 1 *)
  7.2513  
  7.2514 -declare word_roti_def [simp]
  7.2515 +declare word_roti_eq_word_rotr_word_rotl [simp]
  7.2516  
  7.2517  
  7.2518  subsection \<open>Maximum machine word\<close>
  7.2519 @@ -5015,7 +5096,7 @@
  7.2520    by (simp add: linorder_not_less)
  7.2521  
  7.2522  lemma shiftr1_1 [simp]: "shiftr1 (1::'a::len word) = 0"
  7.2523 -  unfolding shiftr1_def by simp
  7.2524 +  by transfer simp
  7.2525  
  7.2526  lemma shiftr_1[simp]: "(1::'a::len word) >> n = (if n = 0 then 1 else 0)"
  7.2527    by (induct n) (auto simp: shiftr_def)
  7.2528 @@ -5100,7 +5181,10 @@
  7.2529    by (simp add: word_arith_wis int_word_uint mod_sub_if_z word_size)
  7.2530  
  7.2531  lemma unat_sub: "b \<le> a \<Longrightarrow> unat (a - b) = unat a - unat b"
  7.2532 -  by (simp add: unat_def uint_sub_if_size word_le_def nat_diff_distrib)
  7.2533 +  apply transfer
  7.2534 +  apply (simp flip: nat_diff_distrib)
  7.2535 +  apply (metis minus_word.abs_eq uint_sub_lem word_ubin.eq_norm)
  7.2536 +  done
  7.2537  
  7.2538  lemmas word_less_sub1_numberof [simp] = word_less_sub1 [of "numeral w"] for w
  7.2539  lemmas word_le_sub1_numberof [simp] = word_le_sub1 [of "numeral w"] for w
  7.2540 @@ -5290,43 +5374,28 @@
  7.2541    by (fact shiftl_x_0)
  7.2542  
  7.2543  lemma mask_1: "mask 1 = 1"
  7.2544 -  by (simp add: mask_def)
  7.2545 +  by transfer (simp add: min_def mask_Suc_exp)
  7.2546  
  7.2547  lemma mask_Suc_0: "mask (Suc 0) = 1"
  7.2548 -  by (simp add: mask_def)
  7.2549 +  using mask_1 by simp
  7.2550  
  7.2551  lemma mask_numeral: "mask (numeral n) = 2 * mask (pred_numeral n) + 1"
  7.2552 -  by (simp add: mask_def neg_numeral_class.sub_def numeral_eq_Suc numeral_pow)
  7.2553 +  by (simp add: mask_Suc_rec numeral_eq_Suc)
  7.2554  
  7.2555  lemma bin_last_bintrunc: "bin_last (bintrunc l n) = (l > 0 \<and> bin_last n)"
  7.2556 -  by (cases l) simp_all
  7.2557 +  by simp
  7.2558  
  7.2559  lemma word_and_1:
  7.2560    "n AND 1 = (if n !! 0 then 1 else 0)" for n :: "_ word"
  7.2561 -  by transfer (rule bin_rl_eqI, simp_all add: bin_rest_trunc bin_last_bintrunc)
  7.2562 +  by (rule bit_word_eqI) (auto simp add: bit_and_iff test_bit_eq_bit bit_1_iff intro: gr0I)
  7.2563  
  7.2564  lemma bintrunc_shiftl:
  7.2565    "bintrunc n (m << i) = bintrunc (n - i) m << i"
  7.2566 -proof (induction i arbitrary: n)
  7.2567 -  case 0
  7.2568 -  show ?case
  7.2569 -    by simp
  7.2570 -next
  7.2571 -  case (Suc i)
  7.2572 -  then show ?case by (cases n) (simp_all add: take_bit_Suc)
  7.2573 -qed
  7.2574 -
  7.2575 -lemma shiftl_transfer [transfer_rule]:
  7.2576 -  includes lifting_syntax
  7.2577 -  shows "(pcr_word ===> (=) ===> pcr_word) (<<) (<<)"
  7.2578 -  by (auto intro!: rel_funI word_eqI simp add: word.pcr_cr_eq cr_word_def word_size nth_shiftl)
  7.2579 +  by (rule bit_eqI) (auto simp add: bit_take_bit_iff)
  7.2580  
  7.2581  lemma uint_shiftl:
  7.2582    "uint (n << i) = bintrunc (size n) (uint n << i)"
  7.2583 -  apply (simp add: word_size shiftl_eq_push_bit shiftl_word_eq)
  7.2584 -  apply transfer
  7.2585 -  apply (simp add: push_bit_take_bit)
  7.2586 -  done
  7.2587 +  by transfer (simp add: push_bit_take_bit shiftl_eq_push_bit)
  7.2588  
  7.2589  
  7.2590  subsection \<open>Misc\<close>
     8.1 --- a/src/HOL/Word/Word_Examples.thy	Wed Jul 29 14:23:19 2020 +0200
     8.2 +++ b/src/HOL/Word/Word_Examples.thy	Sat Aug 01 17:43:30 2020 +0000
     8.3 @@ -80,14 +80,9 @@
     8.4  
     8.5  lemma "to_bl (0b110::4 word) = [False, True, True, False]" by simp
     8.6  
     8.7 -text "this is not exactly fast, but bearable"
     8.8  lemma "of_bl (replicate 32 True) = (0xFFFFFFFF::32 word)"
     8.9    by (simp add: numeral_eq_Suc)
    8.10  
    8.11 -text "this works only for replicate n True"
    8.12 -lemma "of_bl (replicate 32 True) = (0xFFFFFFFF::32 word)"
    8.13 -  by (unfold mask_bl [symmetric]) (simp add: mask_def)
    8.14 -
    8.15  
    8.16  text "bit operations"
    8.17  
     9.1 --- a/src/HOL/ex/Word.thy	Wed Jul 29 14:23:19 2020 +0200
     9.2 +++ b/src/HOL/ex/Word.thy	Sat Aug 01 17:43:30 2020 +0000
     9.3 @@ -192,7 +192,7 @@
     9.4  
     9.5  lemma of_int_signed [simp]:
     9.6    "of_int (signed a) = a"
     9.7 -  by (transfer; cases \<open>LENGTH('a)\<close>) simp_all
     9.8 +  by transfer (simp_all add: take_bit_signed_take_bit)
     9.9  
    9.10  
    9.11  subsubsection \<open>Properties\<close>