src/HOL/Word/Word.thy
changeset 37660 56e3520b68b2
parent 36899 bcd6fce5bf06
child 37667 41acc0fa6b6c
equal deleted inserted replaced
37659:14cabf5fa710 37660:56e3520b68b2
     1 (*  Title:      HOL/Word/Word.thy
     1 (*  Title:      HOL/Word/Word.thy
     2     Author:     Gerwin Klein, NICTA
     2     Author: Jeremy Dawson and Gerwin Klein, NICTA
     3 *)
     3 *)
     4 
     4 
     5 header {* Word Library interface *}
     5 header {* A type of finite bit strings *}
     6 
     6 
     7 theory Word
     7 theory Word
     8 imports WordGenLib
     8 imports Type_Length Misc_Typedef Boolean_Algebra Bool_List_Representation
     9 uses "~~/src/HOL/Tools/SMT/smt_word.ML"
     9 uses ("~~/src/HOL/Tools/SMT/smt_word.ML")
    10 begin
    10 begin
    11 
    11 
       
    12 text {* see @{text "Examples/WordExamples.thy"} for examples *}
       
    13 
       
    14 subsection {* Type definition *}
       
    15 
       
    16 typedef (open word) 'a word = "{(0::int) ..< 2^len_of TYPE('a::len0)}"
       
    17   morphisms uint Abs_word by auto
       
    18 
       
    19 definition word_of_int :: "int \<Rightarrow> 'a\<Colon>len0 word" where
       
    20   -- {* representation of words using unsigned or signed bins, 
       
    21         only difference in these is the type class *}
       
    22   "word_of_int w = Abs_word (bintrunc (len_of TYPE ('a)) w)" 
       
    23 
       
    24 lemma uint_word_of_int [code]: "uint (word_of_int w \<Colon> 'a\<Colon>len0 word) = w mod 2 ^ len_of TYPE('a)"
       
    25   by (auto simp add: word_of_int_def bintrunc_mod2p intro: Abs_word_inverse)
       
    26 
       
    27 code_datatype word_of_int
       
    28 
       
    29 notation fcomp (infixl "o>" 60)
       
    30 notation scomp (infixl "o\<rightarrow>" 60)
       
    31 
       
    32 instantiation word :: ("{len0, typerep}") random
       
    33 begin
       
    34 
       
    35 definition
       
    36   "random_word i = Random.range (max i (2 ^ len_of TYPE('a))) o\<rightarrow> (\<lambda>k. Pair (
       
    37      let j = word_of_int (Code_Numeral.int_of k) :: 'a word
       
    38      in (j, \<lambda>_::unit. Code_Evaluation.term_of j)))"
       
    39 
       
    40 instance ..
       
    41 
       
    42 end
       
    43 
       
    44 no_notation fcomp (infixl "o>" 60)
       
    45 no_notation scomp (infixl "o\<rightarrow>" 60)
       
    46 
       
    47 
       
    48 subsection {* Type conversions and casting *}
       
    49 
       
    50 definition sint :: "'a :: len word => int" where
       
    51   -- {* treats the most-significant-bit as a sign bit *}
       
    52   sint_uint: "sint w = sbintrunc (len_of TYPE ('a) - 1) (uint w)"
       
    53 
       
    54 definition unat :: "'a :: len0 word => nat" where
       
    55   "unat w = nat (uint w)"
       
    56 
       
    57 definition uints :: "nat => int set" where
       
    58   -- "the sets of integers representing the words"
       
    59   "uints n = range (bintrunc n)"
       
    60 
       
    61 definition sints :: "nat => int set" where
       
    62   "sints n = range (sbintrunc (n - 1))"
       
    63 
       
    64 definition unats :: "nat => nat set" where
       
    65   "unats n = {i. i < 2 ^ n}"
       
    66 
       
    67 definition norm_sint :: "nat => int => int" where
       
    68   "norm_sint n w = (w + 2 ^ (n - 1)) mod 2 ^ n - 2 ^ (n - 1)"
       
    69 
       
    70 definition scast :: "'a :: len word => 'b :: len word" where
       
    71   -- "cast a word to a different length"
       
    72   "scast w = word_of_int (sint w)"
       
    73 
       
    74 definition ucast :: "'a :: len0 word => 'b :: len0 word" where
       
    75   "ucast w = word_of_int (uint w)"
       
    76 
       
    77 instantiation word :: (len0) size
       
    78 begin
       
    79 
       
    80 definition
       
    81   word_size: "size (w :: 'a word) = len_of TYPE('a)"
       
    82 
       
    83 instance ..
       
    84 
       
    85 end
       
    86 
       
    87 definition source_size :: "('a :: len0 word => 'b) => nat" where
       
    88   -- "whether a cast (or other) function is to a longer or shorter length"
       
    89   "source_size c = (let arb = undefined ; x = c arb in size arb)"  
       
    90 
       
    91 definition target_size :: "('a => 'b :: len0 word) => nat" where
       
    92   "target_size c = size (c undefined)"
       
    93 
       
    94 definition is_up :: "('a :: len0 word => 'b :: len0 word) => bool" where
       
    95   "is_up c \<longleftrightarrow> source_size c <= target_size c"
       
    96 
       
    97 definition is_down :: "('a :: len0 word => 'b :: len0 word) => bool" where
       
    98   "is_down c \<longleftrightarrow> target_size c <= source_size c"
       
    99 
       
   100 definition of_bl :: "bool list => 'a :: len0 word" where
       
   101   "of_bl bl = word_of_int (bl_to_bin bl)"
       
   102 
       
   103 definition to_bl :: "'a :: len0 word => bool list" where
       
   104   "to_bl w = bin_to_bl (len_of TYPE ('a)) (uint w)"
       
   105 
       
   106 definition word_reverse :: "'a :: len0 word => 'a word" where
       
   107   "word_reverse w = of_bl (rev (to_bl w))"
       
   108 
       
   109 definition word_int_case :: "(int => 'b) => ('a :: len0 word) => 'b" where
       
   110   "word_int_case f w = f (uint w)"
       
   111 
       
   112 syntax
       
   113   of_int :: "int => 'a"
       
   114 translations
       
   115   "case x of CONST of_int y => b" == "CONST word_int_case (%y. b) x"
       
   116 
       
   117 
       
   118 subsection  "Arithmetic operations"
       
   119 
       
   120 instantiation word :: (len0) "{number, uminus, minus, plus, one, zero, times, Divides.div, ord, bit}"
       
   121 begin
       
   122 
       
   123 definition
       
   124   word_0_wi: "0 = word_of_int 0"
       
   125 
       
   126 definition
       
   127   word_1_wi: "1 = word_of_int 1"
       
   128 
       
   129 definition
       
   130   word_add_def: "a + b = word_of_int (uint a + uint b)"
       
   131 
       
   132 definition
       
   133   word_sub_wi: "a - b = word_of_int (uint a - uint b)"
       
   134 
       
   135 definition
       
   136   word_minus_def: "- a = word_of_int (- uint a)"
       
   137 
       
   138 definition
       
   139   word_mult_def: "a * b = word_of_int (uint a * uint b)"
       
   140 
       
   141 definition
       
   142   word_div_def: "a div b = word_of_int (uint a div uint b)"
       
   143 
       
   144 definition
       
   145   word_mod_def: "a mod b = word_of_int (uint a mod uint b)"
       
   146 
       
   147 definition
       
   148   word_number_of_def: "number_of w = word_of_int w"
       
   149 
       
   150 definition
       
   151   word_le_def: "a \<le> b \<longleftrightarrow> uint a \<le> uint b"
       
   152 
       
   153 definition
       
   154   word_less_def: "x < y \<longleftrightarrow> x \<le> y \<and> x \<noteq> (y \<Colon> 'a word)"
       
   155 
       
   156 definition
       
   157   word_and_def: 
       
   158   "(a::'a word) AND b = word_of_int (uint a AND uint b)"
       
   159 
       
   160 definition
       
   161   word_or_def:  
       
   162   "(a::'a word) OR b = word_of_int (uint a OR uint b)"
       
   163 
       
   164 definition
       
   165   word_xor_def: 
       
   166   "(a::'a word) XOR b = word_of_int (uint a XOR uint b)"
       
   167 
       
   168 definition
       
   169   word_not_def: 
       
   170   "NOT (a::'a word) = word_of_int (NOT (uint a))"
       
   171 
       
   172 instance ..
       
   173 
       
   174 end
       
   175 
       
   176 definition
       
   177   word_succ :: "'a :: len0 word => 'a word"
       
   178 where
       
   179   "word_succ a = word_of_int (Int.succ (uint a))"
       
   180 
       
   181 definition
       
   182   word_pred :: "'a :: len0 word => 'a word"
       
   183 where
       
   184   "word_pred a = word_of_int (Int.pred (uint a))"
       
   185 
       
   186 definition udvd :: "'a::len word => 'a::len word => bool" (infixl "udvd" 50) where
       
   187   "a udvd b == EX n>=0. uint b = n * uint a"
       
   188 
       
   189 definition word_sle :: "'a :: len word => 'a word => bool" ("(_/ <=s _)" [50, 51] 50) where
       
   190   "a <=s b == sint a <= sint b"
       
   191 
       
   192 definition word_sless :: "'a :: len word => 'a word => bool" ("(_/ <s _)" [50, 51] 50) where
       
   193   "(x <s y) == (x <=s y & x ~= y)"
       
   194 
       
   195 
       
   196 
       
   197 subsection "Bit-wise operations"
       
   198 
       
   199 instantiation word :: (len0) bits
       
   200 begin
       
   201 
       
   202 definition
       
   203   word_test_bit_def: "test_bit a = bin_nth (uint a)"
       
   204 
       
   205 definition
       
   206   word_set_bit_def: "set_bit a n x =
       
   207    word_of_int (bin_sc n (If x 1 0) (uint a))"
       
   208 
       
   209 definition
       
   210   word_set_bits_def: "(BITS n. f n) = of_bl (bl_of_nth (len_of TYPE ('a)) f)"
       
   211 
       
   212 definition
       
   213   word_lsb_def: "lsb a \<longleftrightarrow> bin_last (uint a) = 1"
       
   214 
       
   215 definition shiftl1 :: "'a word \<Rightarrow> 'a word" where
       
   216   "shiftl1 w = word_of_int (uint w BIT 0)"
       
   217 
       
   218 definition shiftr1 :: "'a word \<Rightarrow> 'a word" where
       
   219   -- "shift right as unsigned or as signed, ie logical or arithmetic"
       
   220   "shiftr1 w = word_of_int (bin_rest (uint w))"
       
   221 
       
   222 definition
       
   223   shiftl_def: "w << n = (shiftl1 ^^ n) w"
       
   224 
       
   225 definition
       
   226   shiftr_def: "w >> n = (shiftr1 ^^ n) w"
       
   227 
       
   228 instance ..
       
   229 
       
   230 end
       
   231 
       
   232 instantiation word :: (len) bitss
       
   233 begin
       
   234 
       
   235 definition
       
   236   word_msb_def: 
       
   237   "msb a \<longleftrightarrow> bin_sign (sint a) = Int.Min"
       
   238 
       
   239 instance ..
       
   240 
       
   241 end
       
   242 
       
   243 definition setBit :: "'a :: len0 word => nat => 'a word" where 
       
   244   "setBit w n == set_bit w n True"
       
   245 
       
   246 definition clearBit :: "'a :: len0 word => nat => 'a word" where
       
   247   "clearBit w n == set_bit w n False"
       
   248 
       
   249 
       
   250 subsection "Shift operations"
       
   251 
       
   252 definition sshiftr1 :: "'a :: len word => 'a word" where 
       
   253   "sshiftr1 w == word_of_int (bin_rest (sint w))"
       
   254 
       
   255 definition bshiftr1 :: "bool => 'a :: len word => 'a word" where
       
   256   "bshiftr1 b w == of_bl (b # butlast (to_bl w))"
       
   257 
       
   258 definition sshiftr :: "'a :: len word => nat => 'a word" (infixl ">>>" 55) where
       
   259   "w >>> n == (sshiftr1 ^^ n) w"
       
   260 
       
   261 definition mask :: "nat => 'a::len word" where
       
   262   "mask n == (1 << n) - 1"
       
   263 
       
   264 definition revcast :: "'a :: len0 word => 'b :: len0 word" where
       
   265   "revcast w ==  of_bl (takefill False (len_of TYPE('b)) (to_bl w))"
       
   266 
       
   267 definition slice1 :: "nat => 'a :: len0 word => 'b :: len0 word" where
       
   268   "slice1 n w == of_bl (takefill False n (to_bl w))"
       
   269 
       
   270 definition slice :: "nat => 'a :: len0 word => 'b :: len0 word" where
       
   271   "slice n w == slice1 (size w - n) w"
       
   272 
       
   273 
       
   274 subsection "Rotation"
       
   275 
       
   276 definition rotater1 :: "'a list => 'a list" where
       
   277   "rotater1 ys == 
       
   278     case ys of [] => [] | x # xs => last ys # butlast ys"
       
   279 
       
   280 definition rotater :: "nat => 'a list => 'a list" where
       
   281   "rotater n == rotater1 ^^ n"
       
   282 
       
   283 definition word_rotr :: "nat => 'a :: len0 word => 'a :: len0 word" where
       
   284   "word_rotr n w == of_bl (rotater n (to_bl w))"
       
   285 
       
   286 definition word_rotl :: "nat => 'a :: len0 word => 'a :: len0 word" where
       
   287   "word_rotl n w == of_bl (rotate n (to_bl w))"
       
   288 
       
   289 definition word_roti :: "int => 'a :: len0 word => 'a :: len0 word" where
       
   290   "word_roti i w == if i >= 0 then word_rotr (nat i) w
       
   291                     else word_rotl (nat (- i)) w"
       
   292 
       
   293 
       
   294 subsection "Split and cat operations"
       
   295 
       
   296 definition word_cat :: "'a :: len0 word => 'b :: len0 word => 'c :: len0 word" where
       
   297   "word_cat a b == word_of_int (bin_cat (uint a) (len_of TYPE ('b)) (uint b))"
       
   298 
       
   299 definition word_split :: "'a :: len0 word => ('b :: len0 word) * ('c :: len0 word)" where
       
   300   "word_split a == 
       
   301    case bin_split (len_of TYPE ('c)) (uint a) of 
       
   302      (u, v) => (word_of_int u, word_of_int v)"
       
   303 
       
   304 definition word_rcat :: "'a :: len0 word list => 'b :: len0 word" where
       
   305   "word_rcat ws == 
       
   306   word_of_int (bin_rcat (len_of TYPE ('a)) (map uint ws))"
       
   307 
       
   308 definition word_rsplit :: "'a :: len0 word => 'b :: len word list" where
       
   309   "word_rsplit w == 
       
   310   map word_of_int (bin_rsplit (len_of TYPE ('b)) (len_of TYPE ('a), uint w))"
       
   311 
       
   312 definition max_word :: "'a::len word" -- "Largest representable machine integer." where
       
   313   "max_word \<equiv> word_of_int (2 ^ len_of TYPE('a) - 1)"
       
   314 
       
   315 primrec of_bool :: "bool \<Rightarrow> 'a::len word" where
       
   316   "of_bool False = 0"
       
   317 | "of_bool True = 1"
       
   318 
       
   319 
       
   320 lemmas of_nth_def = word_set_bits_def
       
   321 
       
   322 lemmas word_size_gt_0 [iff] = 
       
   323   xtr1 [OF word_size len_gt_0, standard]
       
   324 lemmas lens_gt_0 = word_size_gt_0 len_gt_0
       
   325 lemmas lens_not_0 [iff] = lens_gt_0 [THEN gr_implies_not0, standard]
       
   326 
       
   327 lemma uints_num: "uints n = {i. 0 \<le> i \<and> i < 2 ^ n}"
       
   328   by (simp add: uints_def range_bintrunc)
       
   329 
       
   330 lemma sints_num: "sints n = {i. - (2 ^ (n - 1)) \<le> i \<and> i < 2 ^ (n - 1)}"
       
   331   by (simp add: sints_def range_sbintrunc)
       
   332 
       
   333 lemmas atLeastLessThan_alt = atLeastLessThan_def [unfolded 
       
   334   atLeast_def lessThan_def Collect_conj_eq [symmetric]]
       
   335   
       
   336 lemma mod_in_reps: "m > 0 ==> y mod m : {0::int ..< m}"
       
   337   unfolding atLeastLessThan_alt by auto
       
   338 
       
   339 lemma 
       
   340   uint_0:"0 <= uint x" and 
       
   341   uint_lt: "uint (x::'a::len0 word) < 2 ^ len_of TYPE('a)"
       
   342   by (auto simp: uint [simplified])
       
   343 
       
   344 lemma uint_mod_same:
       
   345   "uint x mod 2 ^ len_of TYPE('a) = uint (x::'a::len0 word)"
       
   346   by (simp add: int_mod_eq uint_lt uint_0)
       
   347 
       
   348 lemma td_ext_uint: 
       
   349   "td_ext (uint :: 'a word => int) word_of_int (uints (len_of TYPE('a::len0))) 
       
   350     (%w::int. w mod 2 ^ len_of TYPE('a))"
       
   351   apply (unfold td_ext_def')
       
   352   apply (simp add: uints_num word_of_int_def bintrunc_mod2p)
       
   353   apply (simp add: uint_mod_same uint_0 uint_lt
       
   354                    word.uint_inverse word.Abs_word_inverse int_mod_lem)
       
   355   done
       
   356 
       
   357 lemmas int_word_uint = td_ext_uint [THEN td_ext.eq_norm, standard]
       
   358 
       
   359 interpretation word_uint:
       
   360   td_ext "uint::'a::len0 word \<Rightarrow> int" 
       
   361          word_of_int 
       
   362          "uints (len_of TYPE('a::len0))"
       
   363          "\<lambda>w. w mod 2 ^ len_of TYPE('a::len0)"
       
   364   by (rule td_ext_uint)
       
   365   
       
   366 lemmas td_uint = word_uint.td_thm
       
   367 
       
   368 lemmas td_ext_ubin = td_ext_uint 
       
   369   [simplified len_gt_0 no_bintr_alt1 [symmetric]]
       
   370 
       
   371 interpretation word_ubin:
       
   372   td_ext "uint::'a::len0 word \<Rightarrow> int" 
       
   373          word_of_int 
       
   374          "uints (len_of TYPE('a::len0))"
       
   375          "bintrunc (len_of TYPE('a::len0))"
       
   376   by (rule td_ext_ubin)
       
   377 
       
   378 lemma sint_sbintrunc': 
       
   379   "sint (word_of_int bin :: 'a word) = 
       
   380     (sbintrunc (len_of TYPE ('a :: len) - 1) bin)"
       
   381   unfolding sint_uint 
       
   382   by (auto simp: word_ubin.eq_norm sbintrunc_bintrunc_lt)
       
   383 
       
   384 lemma uint_sint: 
       
   385   "uint w = bintrunc (len_of TYPE('a)) (sint (w :: 'a :: len word))"
       
   386   unfolding sint_uint by (auto simp: bintrunc_sbintrunc_le)
       
   387 
       
   388 lemma bintr_uint': 
       
   389   "n >= size w ==> bintrunc n (uint w) = uint w"
       
   390   apply (unfold word_size)
       
   391   apply (subst word_ubin.norm_Rep [symmetric]) 
       
   392   apply (simp only: bintrunc_bintrunc_min word_size)
       
   393   apply (simp add: min_max.inf_absorb2)
       
   394   done
       
   395 
       
   396 lemma wi_bintr': 
       
   397   "wb = word_of_int bin ==> n >= size wb ==> 
       
   398     word_of_int (bintrunc n bin) = wb"
       
   399   unfolding word_size
       
   400   by (clarsimp simp add: word_ubin.norm_eq_iff [symmetric] min_max.inf_absorb1)
       
   401 
       
   402 lemmas bintr_uint = bintr_uint' [unfolded word_size]
       
   403 lemmas wi_bintr = wi_bintr' [unfolded word_size]
       
   404 
       
   405 lemma td_ext_sbin: 
       
   406   "td_ext (sint :: 'a word => int) word_of_int (sints (len_of TYPE('a::len))) 
       
   407     (sbintrunc (len_of TYPE('a) - 1))"
       
   408   apply (unfold td_ext_def' sint_uint)
       
   409   apply (simp add : word_ubin.eq_norm)
       
   410   apply (cases "len_of TYPE('a)")
       
   411    apply (auto simp add : sints_def)
       
   412   apply (rule sym [THEN trans])
       
   413   apply (rule word_ubin.Abs_norm)
       
   414   apply (simp only: bintrunc_sbintrunc)
       
   415   apply (drule sym)
       
   416   apply simp
       
   417   done
       
   418 
       
   419 lemmas td_ext_sint = td_ext_sbin 
       
   420   [simplified len_gt_0 no_sbintr_alt2 Suc_pred' [symmetric]]
       
   421 
       
   422 (* We do sint before sbin, before sint is the user version
       
   423    and interpretations do not produce thm duplicates. I.e. 
       
   424    we get the name word_sint.Rep_eqD, but not word_sbin.Req_eqD,
       
   425    because the latter is the same thm as the former *)
       
   426 interpretation word_sint:
       
   427   td_ext "sint ::'a::len word => int" 
       
   428           word_of_int 
       
   429           "sints (len_of TYPE('a::len))"
       
   430           "%w. (w + 2^(len_of TYPE('a::len) - 1)) mod 2^len_of TYPE('a::len) -
       
   431                2 ^ (len_of TYPE('a::len) - 1)"
       
   432   by (rule td_ext_sint)
       
   433 
       
   434 interpretation word_sbin:
       
   435   td_ext "sint ::'a::len word => int" 
       
   436           word_of_int 
       
   437           "sints (len_of TYPE('a::len))"
       
   438           "sbintrunc (len_of TYPE('a::len) - 1)"
       
   439   by (rule td_ext_sbin)
       
   440 
       
   441 lemmas int_word_sint = td_ext_sint [THEN td_ext.eq_norm, standard]
       
   442 
       
   443 lemmas td_sint = word_sint.td
       
   444 
       
   445 lemma word_number_of_alt: "number_of b == word_of_int (number_of b)"
       
   446   unfolding word_number_of_def by (simp add: number_of_eq)
       
   447 
       
   448 lemma word_no_wi: "number_of = word_of_int"
       
   449   by (auto simp: word_number_of_def intro: ext)
       
   450 
       
   451 lemma to_bl_def': 
       
   452   "(to_bl :: 'a :: len0 word => bool list) =
       
   453     bin_to_bl (len_of TYPE('a)) o uint"
       
   454   by (auto simp: to_bl_def intro: ext)
       
   455 
       
   456 lemmas word_reverse_no_def [simp] = word_reverse_def [of "number_of w", standard]
       
   457 
       
   458 lemmas uints_mod = uints_def [unfolded no_bintr_alt1]
       
   459 
       
   460 lemma uint_bintrunc: "uint (number_of bin :: 'a word) = 
       
   461     number_of (bintrunc (len_of TYPE ('a :: len0)) bin)"
       
   462   unfolding word_number_of_def number_of_eq
       
   463   by (auto intro: word_ubin.eq_norm) 
       
   464 
       
   465 lemma sint_sbintrunc: "sint (number_of bin :: 'a word) = 
       
   466     number_of (sbintrunc (len_of TYPE ('a :: len) - 1) bin)" 
       
   467   unfolding word_number_of_def number_of_eq
       
   468   by (subst word_sbin.eq_norm) simp
       
   469 
       
   470 lemma unat_bintrunc: 
       
   471   "unat (number_of bin :: 'a :: len0 word) =
       
   472     number_of (bintrunc (len_of TYPE('a)) bin)"
       
   473   unfolding unat_def nat_number_of_def 
       
   474   by (simp only: uint_bintrunc)
       
   475 
       
   476 (* WARNING - these may not always be helpful *)
       
   477 declare 
       
   478   uint_bintrunc [simp] 
       
   479   sint_sbintrunc [simp] 
       
   480   unat_bintrunc [simp]
       
   481 
       
   482 lemma size_0_eq: "size (w :: 'a :: len0 word) = 0 ==> v = w"
       
   483   apply (unfold word_size)
       
   484   apply (rule word_uint.Rep_eqD)
       
   485   apply (rule box_equals)
       
   486     defer
       
   487     apply (rule word_ubin.norm_Rep)+
       
   488   apply simp
       
   489   done
       
   490 
       
   491 lemmas uint_lem = word_uint.Rep [unfolded uints_num mem_Collect_eq]
       
   492 lemmas sint_lem = word_sint.Rep [unfolded sints_num mem_Collect_eq]
       
   493 lemmas uint_ge_0 [iff] = uint_lem [THEN conjunct1, standard]
       
   494 lemmas uint_lt2p [iff] = uint_lem [THEN conjunct2, standard]
       
   495 lemmas sint_ge = sint_lem [THEN conjunct1, standard]
       
   496 lemmas sint_lt = sint_lem [THEN conjunct2, standard]
       
   497 
       
   498 lemma sign_uint_Pls [simp]: 
       
   499   "bin_sign (uint x) = Int.Pls"
       
   500   by (simp add: sign_Pls_ge_0 number_of_eq)
       
   501 
       
   502 lemmas uint_m2p_neg = iffD2 [OF diff_less_0_iff_less uint_lt2p, standard]
       
   503 lemmas uint_m2p_not_non_neg = 
       
   504   iffD2 [OF linorder_not_le uint_m2p_neg, standard]
       
   505 
       
   506 lemma lt2p_lem:
       
   507   "len_of TYPE('a) <= n ==> uint (w :: 'a :: len0 word) < 2 ^ n"
       
   508   by (rule xtr8 [OF _ uint_lt2p]) simp
       
   509 
       
   510 lemmas uint_le_0_iff [simp] = 
       
   511   uint_ge_0 [THEN leD, THEN linorder_antisym_conv1, standard]
       
   512 
       
   513 lemma uint_nat: "uint w == int (unat w)"
       
   514   unfolding unat_def by auto
       
   515 
       
   516 lemma uint_number_of:
       
   517   "uint (number_of b :: 'a :: len0 word) = number_of b mod 2 ^ len_of TYPE('a)"
       
   518   unfolding word_number_of_alt
       
   519   by (simp only: int_word_uint)
       
   520 
       
   521 lemma unat_number_of: 
       
   522   "bin_sign b = Int.Pls ==> 
       
   523   unat (number_of b::'a::len0 word) = number_of b mod 2 ^ len_of TYPE ('a)"
       
   524   apply (unfold unat_def)
       
   525   apply (clarsimp simp only: uint_number_of)
       
   526   apply (rule nat_mod_distrib [THEN trans])
       
   527     apply (erule sign_Pls_ge_0 [THEN iffD1])
       
   528    apply (simp_all add: nat_power_eq)
       
   529   done
       
   530 
       
   531 lemma sint_number_of: "sint (number_of b :: 'a :: len word) = (number_of b + 
       
   532     2 ^ (len_of TYPE('a) - 1)) mod 2 ^ len_of TYPE('a) -
       
   533     2 ^ (len_of TYPE('a) - 1)"
       
   534   unfolding word_number_of_alt by (rule int_word_sint)
       
   535 
       
   536 lemma word_of_int_bin [simp] : 
       
   537   "(word_of_int (number_of bin) :: 'a :: len0 word) = (number_of bin)"
       
   538   unfolding word_number_of_alt by auto
       
   539 
       
   540 lemma word_int_case_wi: 
       
   541   "word_int_case f (word_of_int i :: 'b word) = 
       
   542     f (i mod 2 ^ len_of TYPE('b::len0))"
       
   543   unfolding word_int_case_def by (simp add: word_uint.eq_norm)
       
   544 
       
   545 lemma word_int_split: 
       
   546   "P (word_int_case f x) = 
       
   547     (ALL i. x = (word_of_int i :: 'b :: len0 word) & 
       
   548       0 <= i & i < 2 ^ len_of TYPE('b) --> P (f i))"
       
   549   unfolding word_int_case_def
       
   550   by (auto simp: word_uint.eq_norm int_mod_eq')
       
   551 
       
   552 lemma word_int_split_asm: 
       
   553   "P (word_int_case f x) = 
       
   554     (~ (EX n. x = (word_of_int n :: 'b::len0 word) &
       
   555       0 <= n & n < 2 ^ len_of TYPE('b::len0) & ~ P (f n)))"
       
   556   unfolding word_int_case_def
       
   557   by (auto simp: word_uint.eq_norm int_mod_eq')
       
   558   
       
   559 lemmas uint_range' =
       
   560   word_uint.Rep [unfolded uints_num mem_Collect_eq, standard]
       
   561 lemmas sint_range' = word_sint.Rep [unfolded One_nat_def
       
   562   sints_num mem_Collect_eq, standard]
       
   563 
       
   564 lemma uint_range_size: "0 <= uint w & uint w < 2 ^ size w"
       
   565   unfolding word_size by (rule uint_range')
       
   566 
       
   567 lemma sint_range_size:
       
   568   "- (2 ^ (size w - Suc 0)) <= sint w & sint w < 2 ^ (size w - Suc 0)"
       
   569   unfolding word_size by (rule sint_range')
       
   570 
       
   571 lemmas sint_above_size = sint_range_size
       
   572   [THEN conjunct2, THEN [2] xtr8, folded One_nat_def, standard]
       
   573 
       
   574 lemmas sint_below_size = sint_range_size
       
   575   [THEN conjunct1, THEN [2] order_trans, folded One_nat_def, standard]
       
   576 
       
   577 lemma test_bit_eq_iff: "(test_bit (u::'a::len0 word) = test_bit v) = (u = v)"
       
   578   unfolding word_test_bit_def by (simp add: bin_nth_eq_iff)
       
   579 
       
   580 lemma test_bit_size [rule_format] : "(w::'a::len0 word) !! n --> n < size w"
       
   581   apply (unfold word_test_bit_def)
       
   582   apply (subst word_ubin.norm_Rep [symmetric])
       
   583   apply (simp only: nth_bintr word_size)
       
   584   apply fast
       
   585   done
       
   586 
       
   587 lemma word_eqI [rule_format] : 
       
   588   fixes u :: "'a::len0 word"
       
   589   shows "(ALL n. n < size u --> u !! n = v !! n) ==> u = v"
       
   590   apply (rule test_bit_eq_iff [THEN iffD1])
       
   591   apply (rule ext)
       
   592   apply (erule allE)
       
   593   apply (erule impCE)
       
   594    prefer 2
       
   595    apply assumption
       
   596   apply (auto dest!: test_bit_size simp add: word_size)
       
   597   done
       
   598 
       
   599 lemmas word_eqD = test_bit_eq_iff [THEN iffD2, THEN fun_cong, standard]
       
   600 
       
   601 lemma test_bit_bin': "w !! n = (n < size w & bin_nth (uint w) n)"
       
   602   unfolding word_test_bit_def word_size
       
   603   by (simp add: nth_bintr [symmetric])
       
   604 
       
   605 lemmas test_bit_bin = test_bit_bin' [unfolded word_size]
       
   606 
       
   607 lemma bin_nth_uint_imp': "bin_nth (uint w) n --> n < size w"
       
   608   apply (unfold word_size)
       
   609   apply (rule impI)
       
   610   apply (rule nth_bintr [THEN iffD1, THEN conjunct1])
       
   611   apply (subst word_ubin.norm_Rep)
       
   612   apply assumption
       
   613   done
       
   614 
       
   615 lemma bin_nth_sint': 
       
   616   "n >= size w --> bin_nth (sint w) n = bin_nth (sint w) (size w - 1)"
       
   617   apply (rule impI)
       
   618   apply (subst word_sbin.norm_Rep [symmetric])
       
   619   apply (simp add : nth_sbintr word_size)
       
   620   apply auto
       
   621   done
       
   622 
       
   623 lemmas bin_nth_uint_imp = bin_nth_uint_imp' [rule_format, unfolded word_size]
       
   624 lemmas bin_nth_sint = bin_nth_sint' [rule_format, unfolded word_size]
       
   625 
       
   626 (* type definitions theorem for in terms of equivalent bool list *)
       
   627 lemma td_bl: 
       
   628   "type_definition (to_bl :: 'a::len0 word => bool list) 
       
   629                    of_bl  
       
   630                    {bl. length bl = len_of TYPE('a)}"
       
   631   apply (unfold type_definition_def of_bl_def to_bl_def)
       
   632   apply (simp add: word_ubin.eq_norm)
       
   633   apply safe
       
   634   apply (drule sym)
       
   635   apply simp
       
   636   done
       
   637 
       
   638 interpretation word_bl:
       
   639   type_definition "to_bl :: 'a::len0 word => bool list"
       
   640                   of_bl  
       
   641                   "{bl. length bl = len_of TYPE('a::len0)}"
       
   642   by (rule td_bl)
       
   643 
       
   644 lemma word_size_bl: "size w == size (to_bl w)"
       
   645   unfolding word_size by auto
       
   646 
       
   647 lemma to_bl_use_of_bl:
       
   648   "(to_bl w = bl) = (w = of_bl bl \<and> length bl = length (to_bl w))"
       
   649   by (fastsimp elim!: word_bl.Abs_inverse [simplified])
       
   650 
       
   651 lemma to_bl_word_rev: "to_bl (word_reverse w) = rev (to_bl w)"
       
   652   unfolding word_reverse_def by (simp add: word_bl.Abs_inverse)
       
   653 
       
   654 lemma word_rev_rev [simp] : "word_reverse (word_reverse w) = w"
       
   655   unfolding word_reverse_def by (simp add : word_bl.Abs_inverse)
       
   656 
       
   657 lemma word_rev_gal: "word_reverse w = u ==> word_reverse u = w"
       
   658   by auto
       
   659 
       
   660 lemmas word_rev_gal' = sym [THEN word_rev_gal, symmetric, standard]
       
   661 
       
   662 lemmas length_bl_gt_0 [iff] = xtr1 [OF word_bl.Rep' len_gt_0, standard]
       
   663 lemmas bl_not_Nil [iff] = 
       
   664   length_bl_gt_0 [THEN length_greater_0_conv [THEN iffD1], standard]
       
   665 lemmas length_bl_neq_0 [iff] = length_bl_gt_0 [THEN gr_implies_not0]
       
   666 
       
   667 lemma hd_bl_sign_sint: "hd (to_bl w) = (bin_sign (sint w) = Int.Min)"
       
   668   apply (unfold to_bl_def sint_uint)
       
   669   apply (rule trans [OF _ bl_sbin_sign])
       
   670   apply simp
       
   671   done
       
   672 
       
   673 lemma of_bl_drop': 
       
   674   "lend = length bl - len_of TYPE ('a :: len0) ==> 
       
   675     of_bl (drop lend bl) = (of_bl bl :: 'a word)"
       
   676   apply (unfold of_bl_def)
       
   677   apply (clarsimp simp add : trunc_bl2bin [symmetric])
       
   678   done
       
   679 
       
   680 lemmas of_bl_no = of_bl_def [folded word_number_of_def]
       
   681 
       
   682 lemma test_bit_of_bl:  
       
   683   "(of_bl bl::'a::len0 word) !! n = (rev bl ! n \<and> n < len_of TYPE('a) \<and> n < length bl)"
       
   684   apply (unfold of_bl_def word_test_bit_def)
       
   685   apply (auto simp add: word_size word_ubin.eq_norm nth_bintr bin_nth_of_bl)
       
   686   done
       
   687 
       
   688 lemma no_of_bl: 
       
   689   "(number_of bin ::'a::len0 word) = of_bl (bin_to_bl (len_of TYPE ('a)) bin)"
       
   690   unfolding word_size of_bl_no by (simp add : word_number_of_def)
       
   691 
       
   692 lemma uint_bl: "to_bl w == bin_to_bl (size w) (uint w)"
       
   693   unfolding word_size to_bl_def by auto
       
   694 
       
   695 lemma to_bl_bin: "bl_to_bin (to_bl w) = uint w"
       
   696   unfolding uint_bl by (simp add : word_size)
       
   697 
       
   698 lemma to_bl_of_bin: 
       
   699   "to_bl (word_of_int bin::'a::len0 word) = bin_to_bl (len_of TYPE('a)) bin"
       
   700   unfolding uint_bl by (clarsimp simp add: word_ubin.eq_norm word_size)
       
   701 
       
   702 lemmas to_bl_no_bin [simp] = to_bl_of_bin [folded word_number_of_def]
       
   703 
       
   704 lemma to_bl_to_bin [simp] : "bl_to_bin (to_bl w) = uint w"
       
   705   unfolding uint_bl by (simp add : word_size)
       
   706   
       
   707 lemmas uint_bl_bin [simp] = trans [OF bin_bl_bin word_ubin.norm_Rep, standard]
       
   708 
       
   709 lemmas num_AB_u [simp] = word_uint.Rep_inverse 
       
   710   [unfolded o_def word_number_of_def [symmetric], standard]
       
   711 lemmas num_AB_s [simp] = word_sint.Rep_inverse 
       
   712   [unfolded o_def word_number_of_def [symmetric], standard]
       
   713 
       
   714 (* naturals *)
       
   715 lemma uints_unats: "uints n = int ` unats n"
       
   716   apply (unfold unats_def uints_num)
       
   717   apply safe
       
   718   apply (rule_tac image_eqI)
       
   719   apply (erule_tac nat_0_le [symmetric])
       
   720   apply auto
       
   721   apply (erule_tac nat_less_iff [THEN iffD2])
       
   722   apply (rule_tac [2] zless_nat_eq_int_zless [THEN iffD1])
       
   723   apply (auto simp add : nat_power_eq int_power)
       
   724   done
       
   725 
       
   726 lemma unats_uints: "unats n = nat ` uints n"
       
   727   by (auto simp add : uints_unats image_iff)
       
   728 
       
   729 lemmas bintr_num = word_ubin.norm_eq_iff 
       
   730   [symmetric, folded word_number_of_def, standard]
       
   731 lemmas sbintr_num = word_sbin.norm_eq_iff 
       
   732   [symmetric, folded word_number_of_def, standard]
       
   733 
       
   734 lemmas num_of_bintr = word_ubin.Abs_norm [folded word_number_of_def, standard]
       
   735 lemmas num_of_sbintr = word_sbin.Abs_norm [folded word_number_of_def, standard];
       
   736     
       
   737 (* don't add these to simpset, since may want bintrunc n w to be simplified;
       
   738   may want these in reverse, but loop as simp rules, so use following *)
       
   739 
       
   740 lemma num_of_bintr':
       
   741   "bintrunc (len_of TYPE('a :: len0)) a = b ==> 
       
   742     number_of a = (number_of b :: 'a word)"
       
   743   apply safe
       
   744   apply (rule_tac num_of_bintr [symmetric])
       
   745   done
       
   746 
       
   747 lemma num_of_sbintr':
       
   748   "sbintrunc (len_of TYPE('a :: len) - 1) a = b ==> 
       
   749     number_of a = (number_of b :: 'a word)"
       
   750   apply safe
       
   751   apply (rule_tac num_of_sbintr [symmetric])
       
   752   done
       
   753 
       
   754 lemmas num_abs_bintr = sym [THEN trans,
       
   755   OF num_of_bintr word_number_of_def, standard]
       
   756 lemmas num_abs_sbintr = sym [THEN trans,
       
   757   OF num_of_sbintr word_number_of_def, standard]
       
   758   
       
   759 (** cast - note, no arg for new length, as it's determined by type of result,
       
   760   thus in "cast w = w, the type means cast to length of w! **)
       
   761 
       
   762 lemma ucast_id: "ucast w = w"
       
   763   unfolding ucast_def by auto
       
   764 
       
   765 lemma scast_id: "scast w = w"
       
   766   unfolding scast_def by auto
       
   767 
       
   768 lemma ucast_bl: "ucast w == of_bl (to_bl w)"
       
   769   unfolding ucast_def of_bl_def uint_bl
       
   770   by (auto simp add : word_size)
       
   771 
       
   772 lemma nth_ucast: 
       
   773   "(ucast w::'a::len0 word) !! n = (w !! n & n < len_of TYPE('a))"
       
   774   apply (unfold ucast_def test_bit_bin)
       
   775   apply (simp add: word_ubin.eq_norm nth_bintr word_size) 
       
   776   apply (fast elim!: bin_nth_uint_imp)
       
   777   done
       
   778 
       
   779 (* for literal u(s)cast *)
       
   780 
       
   781 lemma ucast_bintr [simp]: 
       
   782   "ucast (number_of w ::'a::len0 word) = 
       
   783    number_of (bintrunc (len_of TYPE('a)) w)"
       
   784   unfolding ucast_def by simp
       
   785 
       
   786 lemma scast_sbintr [simp]: 
       
   787   "scast (number_of w ::'a::len word) = 
       
   788    number_of (sbintrunc (len_of TYPE('a) - Suc 0) w)"
       
   789   unfolding scast_def by simp
       
   790 
       
   791 lemmas source_size = source_size_def [unfolded Let_def word_size]
       
   792 lemmas target_size = target_size_def [unfolded Let_def word_size]
       
   793 lemmas is_down = is_down_def [unfolded source_size target_size]
       
   794 lemmas is_up = is_up_def [unfolded source_size target_size]
       
   795 
       
   796 lemmas is_up_down =  trans [OF is_up is_down [symmetric], standard]
       
   797 
       
   798 lemma down_cast_same': "uc = ucast ==> is_down uc ==> uc = scast"
       
   799   apply (unfold is_down)
       
   800   apply safe
       
   801   apply (rule ext)
       
   802   apply (unfold ucast_def scast_def uint_sint)
       
   803   apply (rule word_ubin.norm_eq_iff [THEN iffD1])
       
   804   apply simp
       
   805   done
       
   806 
       
   807 lemma word_rev_tf': 
       
   808   "r = to_bl (of_bl bl) ==> r = rev (takefill False (length r) (rev bl))"
       
   809   unfolding of_bl_def uint_bl
       
   810   by (clarsimp simp add: bl_bin_bl_rtf word_ubin.eq_norm word_size)
       
   811 
       
   812 lemmas word_rev_tf = refl [THEN word_rev_tf', unfolded word_bl.Rep', standard]
       
   813 
       
   814 lemmas word_rep_drop = word_rev_tf [simplified takefill_alt,
       
   815   simplified, simplified rev_take, simplified]
       
   816 
       
   817 lemma to_bl_ucast: 
       
   818   "to_bl (ucast (w::'b::len0 word) ::'a::len0 word) = 
       
   819    replicate (len_of TYPE('a) - len_of TYPE('b)) False @
       
   820    drop (len_of TYPE('b) - len_of TYPE('a)) (to_bl w)"
       
   821   apply (unfold ucast_bl)
       
   822   apply (rule trans)
       
   823    apply (rule word_rep_drop)
       
   824   apply simp
       
   825   done
       
   826 
       
   827 lemma ucast_up_app': 
       
   828   "uc = ucast ==> source_size uc + n = target_size uc ==> 
       
   829     to_bl (uc w) = replicate n False @ (to_bl w)"
       
   830   by (auto simp add : source_size target_size to_bl_ucast)
       
   831 
       
   832 lemma ucast_down_drop': 
       
   833   "uc = ucast ==> source_size uc = target_size uc + n ==> 
       
   834     to_bl (uc w) = drop n (to_bl w)"
       
   835   by (auto simp add : source_size target_size to_bl_ucast)
       
   836 
       
   837 lemma scast_down_drop': 
       
   838   "sc = scast ==> source_size sc = target_size sc + n ==> 
       
   839     to_bl (sc w) = drop n (to_bl w)"
       
   840   apply (subgoal_tac "sc = ucast")
       
   841    apply safe
       
   842    apply simp
       
   843    apply (erule refl [THEN ucast_down_drop'])
       
   844   apply (rule refl [THEN down_cast_same', symmetric])
       
   845   apply (simp add : source_size target_size is_down)
       
   846   done
       
   847 
       
   848 lemma sint_up_scast': 
       
   849   "sc = scast ==> is_up sc ==> sint (sc w) = sint w"
       
   850   apply (unfold is_up)
       
   851   apply safe
       
   852   apply (simp add: scast_def word_sbin.eq_norm)
       
   853   apply (rule box_equals)
       
   854     prefer 3
       
   855     apply (rule word_sbin.norm_Rep)
       
   856    apply (rule sbintrunc_sbintrunc_l)
       
   857    defer
       
   858    apply (subst word_sbin.norm_Rep)
       
   859    apply (rule refl)
       
   860   apply simp
       
   861   done
       
   862 
       
   863 lemma uint_up_ucast':
       
   864   "uc = ucast ==> is_up uc ==> uint (uc w) = uint w"
       
   865   apply (unfold is_up)
       
   866   apply safe
       
   867   apply (rule bin_eqI)
       
   868   apply (fold word_test_bit_def)
       
   869   apply (auto simp add: nth_ucast)
       
   870   apply (auto simp add: test_bit_bin)
       
   871   done
       
   872     
       
   873 lemmas down_cast_same = refl [THEN down_cast_same']
       
   874 lemmas ucast_up_app = refl [THEN ucast_up_app']
       
   875 lemmas ucast_down_drop = refl [THEN ucast_down_drop']
       
   876 lemmas scast_down_drop = refl [THEN scast_down_drop']
       
   877 lemmas uint_up_ucast = refl [THEN uint_up_ucast']
       
   878 lemmas sint_up_scast = refl [THEN sint_up_scast']
       
   879 
       
   880 lemma ucast_up_ucast': "uc = ucast ==> is_up uc ==> ucast (uc w) = ucast w"
       
   881   apply (simp (no_asm) add: ucast_def)
       
   882   apply (clarsimp simp add: uint_up_ucast)
       
   883   done
       
   884     
       
   885 lemma scast_up_scast': "sc = scast ==> is_up sc ==> scast (sc w) = scast w"
       
   886   apply (simp (no_asm) add: scast_def)
       
   887   apply (clarsimp simp add: sint_up_scast)
       
   888   done
       
   889     
       
   890 lemma ucast_of_bl_up': 
       
   891   "w = of_bl bl ==> size bl <= size w ==> ucast w = of_bl bl"
       
   892   by (auto simp add : nth_ucast word_size test_bit_of_bl intro!: word_eqI)
       
   893 
       
   894 lemmas ucast_up_ucast = refl [THEN ucast_up_ucast']
       
   895 lemmas scast_up_scast = refl [THEN scast_up_scast']
       
   896 lemmas ucast_of_bl_up = refl [THEN ucast_of_bl_up']
       
   897 
       
   898 lemmas ucast_up_ucast_id = trans [OF ucast_up_ucast ucast_id]
       
   899 lemmas scast_up_scast_id = trans [OF scast_up_scast scast_id]
       
   900 
       
   901 lemmas isduu = is_up_down [where c = "ucast", THEN iffD2]
       
   902 lemmas isdus = is_up_down [where c = "scast", THEN iffD2]
       
   903 lemmas ucast_down_ucast_id = isduu [THEN ucast_up_ucast_id]
       
   904 lemmas scast_down_scast_id = isdus [THEN ucast_up_ucast_id]
       
   905 
       
   906 lemma up_ucast_surj:
       
   907   "is_up (ucast :: 'b::len0 word => 'a::len0 word) ==> 
       
   908    surj (ucast :: 'a word => 'b word)"
       
   909   by (rule surjI, erule ucast_up_ucast_id)
       
   910 
       
   911 lemma up_scast_surj:
       
   912   "is_up (scast :: 'b::len word => 'a::len word) ==> 
       
   913    surj (scast :: 'a word => 'b word)"
       
   914   by (rule surjI, erule scast_up_scast_id)
       
   915 
       
   916 lemma down_scast_inj:
       
   917   "is_down (scast :: 'b::len word => 'a::len word) ==> 
       
   918    inj_on (ucast :: 'a word => 'b word) A"
       
   919   by (rule inj_on_inverseI, erule scast_down_scast_id)
       
   920 
       
   921 lemma down_ucast_inj:
       
   922   "is_down (ucast :: 'b::len0 word => 'a::len0 word) ==> 
       
   923    inj_on (ucast :: 'a word => 'b word) A"
       
   924   by (rule inj_on_inverseI, erule ucast_down_ucast_id)
       
   925 
       
   926 lemma of_bl_append_same: "of_bl (X @ to_bl w) = w"
       
   927   by (rule word_bl.Rep_eqD) (simp add: word_rep_drop)
       
   928   
       
   929 lemma ucast_down_no': 
       
   930   "uc = ucast ==> is_down uc ==> uc (number_of bin) = number_of bin"
       
   931   apply (unfold word_number_of_def is_down)
       
   932   apply (clarsimp simp add: ucast_def word_ubin.eq_norm)
       
   933   apply (rule word_ubin.norm_eq_iff [THEN iffD1])
       
   934   apply (erule bintrunc_bintrunc_ge)
       
   935   done
       
   936     
       
   937 lemmas ucast_down_no = ucast_down_no' [OF refl]
       
   938 
       
   939 lemma ucast_down_bl': "uc = ucast ==> is_down uc ==> uc (of_bl bl) = of_bl bl"
       
   940   unfolding of_bl_no by clarify (erule ucast_down_no)
       
   941     
       
   942 lemmas ucast_down_bl = ucast_down_bl' [OF refl]
       
   943 
       
   944 lemmas slice_def' = slice_def [unfolded word_size]
       
   945 lemmas test_bit_def' = word_test_bit_def [THEN fun_cong]
       
   946 
       
   947 lemmas word_log_defs = word_and_def word_or_def word_xor_def word_not_def
       
   948 lemmas word_log_bin_defs = word_log_defs
       
   949 
       
   950 text {* Executable equality *}
       
   951 
       
   952 instantiation word :: ("{len0}") eq
       
   953 begin
       
   954 
       
   955 definition eq_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> bool" where
       
   956   "eq_word k l \<longleftrightarrow> HOL.eq (uint k) (uint l)"
       
   957 
       
   958 instance proof
       
   959 qed (simp add: eq eq_word_def)
       
   960 
       
   961 end
       
   962 
       
   963 
       
   964 subsection {* Word Arithmetic *}
       
   965 
       
   966 lemma word_less_alt: "(a < b) = (uint a < uint b)"
       
   967   unfolding word_less_def word_le_def
       
   968   by (auto simp del: word_uint.Rep_inject 
       
   969            simp: word_uint.Rep_inject [symmetric])
       
   970 
       
   971 lemma signed_linorder: "class.linorder word_sle word_sless"
       
   972 proof
       
   973 qed (unfold word_sle_def word_sless_def, auto)
       
   974 
       
   975 interpretation signed: linorder "word_sle" "word_sless"
       
   976   by (rule signed_linorder)
       
   977 
       
   978 lemmas word_arith_wis = 
       
   979   word_add_def word_mult_def word_minus_def 
       
   980   word_succ_def word_pred_def word_0_wi word_1_wi
       
   981 
       
   982 lemma udvdI: 
       
   983   "0 \<le> n ==> uint b = n * uint a ==> a udvd b"
       
   984   by (auto simp: udvd_def)
       
   985 
       
   986 lemmas word_div_no [simp] = 
       
   987   word_div_def [of "number_of a" "number_of b", standard]
       
   988 
       
   989 lemmas word_mod_no [simp] = 
       
   990   word_mod_def [of "number_of a" "number_of b", standard]
       
   991 
       
   992 lemmas word_less_no [simp] = 
       
   993   word_less_def [of "number_of a" "number_of b", standard]
       
   994 
       
   995 lemmas word_le_no [simp] = 
       
   996   word_le_def [of "number_of a" "number_of b", standard]
       
   997 
       
   998 lemmas word_sless_no [simp] = 
       
   999   word_sless_def [of "number_of a" "number_of b", standard]
       
  1000 
       
  1001 lemmas word_sle_no [simp] = 
       
  1002   word_sle_def [of "number_of a" "number_of b", standard]
       
  1003 
       
  1004 (* following two are available in class number_ring, 
       
  1005   but convenient to have them here here;
       
  1006   note - the number_ring versions, numeral_0_eq_0 and numeral_1_eq_1
       
  1007   are in the default simpset, so to use the automatic simplifications for
       
  1008   (eg) sint (number_of bin) on sint 1, must do
       
  1009   (simp add: word_1_no del: numeral_1_eq_1) 
       
  1010   *)
       
  1011 lemmas word_0_wi_Pls = word_0_wi [folded Pls_def]
       
  1012 lemmas word_0_no = word_0_wi_Pls [folded word_no_wi]
       
  1013 
       
  1014 lemma int_one_bin: "(1 :: int) == (Int.Pls BIT 1)"
       
  1015   unfolding Pls_def Bit_def by auto
       
  1016 
       
  1017 lemma word_1_no: 
       
  1018   "(1 :: 'a :: len0 word) == number_of (Int.Pls BIT 1)"
       
  1019   unfolding word_1_wi word_number_of_def int_one_bin by auto
       
  1020 
       
  1021 lemma word_m1_wi: "-1 == word_of_int -1" 
       
  1022   by (rule word_number_of_alt)
       
  1023 
       
  1024 lemma word_m1_wi_Min: "-1 = word_of_int Int.Min"
       
  1025   by (simp add: word_m1_wi number_of_eq)
       
  1026 
       
  1027 lemma word_0_bl: "of_bl [] = 0" 
       
  1028   unfolding word_0_wi of_bl_def by (simp add : Pls_def)
       
  1029 
       
  1030 lemma word_1_bl: "of_bl [True] = 1" 
       
  1031   unfolding word_1_wi of_bl_def
       
  1032   by (simp add : bl_to_bin_def Bit_def Pls_def)
       
  1033 
       
  1034 lemma uint_eq_0 [simp] : "(uint 0 = 0)" 
       
  1035   unfolding word_0_wi
       
  1036   by (simp add: word_ubin.eq_norm Pls_def [symmetric])
       
  1037 
       
  1038 lemma of_bl_0 [simp] : "of_bl (replicate n False) = 0"
       
  1039   by (simp add : word_0_wi of_bl_def bl_to_bin_rep_False Pls_def)
       
  1040 
       
  1041 lemma to_bl_0: 
       
  1042   "to_bl (0::'a::len0 word) = replicate (len_of TYPE('a)) False"
       
  1043   unfolding uint_bl
       
  1044   by (simp add : word_size bin_to_bl_Pls Pls_def [symmetric])
       
  1045 
       
  1046 lemma uint_0_iff: "(uint x = 0) = (x = 0)"
       
  1047   by (auto intro!: word_uint.Rep_eqD)
       
  1048 
       
  1049 lemma unat_0_iff: "(unat x = 0) = (x = 0)"
       
  1050   unfolding unat_def by (auto simp add : nat_eq_iff uint_0_iff)
       
  1051 
       
  1052 lemma unat_0 [simp]: "unat 0 = 0"
       
  1053   unfolding unat_def by auto
       
  1054 
       
  1055 lemma size_0_same': "size w = 0 ==> w = (v :: 'a :: len0 word)"
       
  1056   apply (unfold word_size)
       
  1057   apply (rule box_equals)
       
  1058     defer
       
  1059     apply (rule word_uint.Rep_inverse)+
       
  1060   apply (rule word_ubin.norm_eq_iff [THEN iffD1])
       
  1061   apply simp
       
  1062   done
       
  1063 
       
  1064 lemmas size_0_same = size_0_same' [folded word_size]
       
  1065 
       
  1066 lemmas unat_eq_0 = unat_0_iff
       
  1067 lemmas unat_eq_zero = unat_0_iff
       
  1068 
       
  1069 lemma unat_gt_0: "(0 < unat x) = (x ~= 0)"
       
  1070 by (auto simp: unat_0_iff [symmetric])
       
  1071 
       
  1072 lemma ucast_0 [simp] : "ucast 0 = 0"
       
  1073 unfolding ucast_def
       
  1074 by simp (simp add: word_0_wi)
       
  1075 
       
  1076 lemma sint_0 [simp] : "sint 0 = 0"
       
  1077 unfolding sint_uint
       
  1078 by (simp add: Pls_def [symmetric])
       
  1079 
       
  1080 lemma scast_0 [simp] : "scast 0 = 0"
       
  1081 apply (unfold scast_def)
       
  1082 apply simp
       
  1083 apply (simp add: word_0_wi)
       
  1084 done
       
  1085 
       
  1086 lemma sint_n1 [simp] : "sint -1 = -1"
       
  1087 apply (unfold word_m1_wi_Min)
       
  1088 apply (simp add: word_sbin.eq_norm)
       
  1089 apply (unfold Min_def number_of_eq)
       
  1090 apply simp
       
  1091 done
       
  1092 
       
  1093 lemma scast_n1 [simp] : "scast -1 = -1"
       
  1094   apply (unfold scast_def sint_n1)
       
  1095   apply (unfold word_number_of_alt)
       
  1096   apply (rule refl)
       
  1097   done
       
  1098 
       
  1099 lemma uint_1 [simp] : "uint (1 :: 'a :: len word) = 1"
       
  1100   unfolding word_1_wi
       
  1101   by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps)
       
  1102 
       
  1103 lemma unat_1 [simp] : "unat (1 :: 'a :: len word) = 1"
       
  1104   by (unfold unat_def uint_1) auto
       
  1105 
       
  1106 lemma ucast_1 [simp] : "ucast (1 :: 'a :: len word) = 1"
       
  1107   unfolding ucast_def word_1_wi
       
  1108   by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps)
       
  1109 
       
  1110 (* abstraction preserves the operations
       
  1111   (the definitions tell this for bins in range uint) *)
       
  1112 
       
  1113 lemmas arths = 
       
  1114   bintr_ariths [THEN word_ubin.norm_eq_iff [THEN iffD1],
       
  1115                 folded word_ubin.eq_norm, standard]
       
  1116 
       
  1117 lemma wi_homs: 
       
  1118   shows
       
  1119   wi_hom_add: "word_of_int a + word_of_int b = word_of_int (a + b)" and
       
  1120   wi_hom_mult: "word_of_int a * word_of_int b = word_of_int (a * b)" and
       
  1121   wi_hom_neg: "- word_of_int a = word_of_int (- a)" and
       
  1122   wi_hom_succ: "word_succ (word_of_int a) = word_of_int (Int.succ a)" and
       
  1123   wi_hom_pred: "word_pred (word_of_int a) = word_of_int (Int.pred a)"
       
  1124   by (auto simp: word_arith_wis arths)
       
  1125 
       
  1126 lemmas wi_hom_syms = wi_homs [symmetric]
       
  1127 
       
  1128 lemma word_sub_def: "a - b == a + - (b :: 'a :: len0 word)"
       
  1129   unfolding word_sub_wi diff_def
       
  1130   by (simp only : word_uint.Rep_inverse wi_hom_syms)
       
  1131     
       
  1132 lemmas word_diff_minus = word_sub_def [THEN meta_eq_to_obj_eq, standard]
       
  1133 
       
  1134 lemma word_of_int_sub_hom:
       
  1135   "(word_of_int a) - word_of_int b = word_of_int (a - b)"
       
  1136   unfolding word_sub_def diff_def by (simp only : wi_homs)
       
  1137 
       
  1138 lemmas new_word_of_int_homs = 
       
  1139   word_of_int_sub_hom wi_homs word_0_wi word_1_wi 
       
  1140 
       
  1141 lemmas new_word_of_int_hom_syms = new_word_of_int_homs [symmetric, standard]
       
  1142 
       
  1143 lemmas word_of_int_hom_syms =
       
  1144   new_word_of_int_hom_syms [unfolded succ_def pred_def]
       
  1145 
       
  1146 lemmas word_of_int_homs =
       
  1147   new_word_of_int_homs [unfolded succ_def pred_def]
       
  1148 
       
  1149 lemmas word_of_int_add_hom = word_of_int_homs (2)
       
  1150 lemmas word_of_int_mult_hom = word_of_int_homs (3)
       
  1151 lemmas word_of_int_minus_hom = word_of_int_homs (4)
       
  1152 lemmas word_of_int_succ_hom = word_of_int_homs (5)
       
  1153 lemmas word_of_int_pred_hom = word_of_int_homs (6)
       
  1154 lemmas word_of_int_0_hom = word_of_int_homs (7)
       
  1155 lemmas word_of_int_1_hom = word_of_int_homs (8)
       
  1156 
       
  1157 (* now, to get the weaker results analogous to word_div/mod_def *)
       
  1158 
       
  1159 lemmas word_arith_alts = 
       
  1160   word_sub_wi [unfolded succ_def pred_def, standard]
       
  1161   word_arith_wis [unfolded succ_def pred_def, standard]
       
  1162 
       
  1163 lemmas word_sub_alt = word_arith_alts (1)
       
  1164 lemmas word_add_alt = word_arith_alts (2)
       
  1165 lemmas word_mult_alt = word_arith_alts (3)
       
  1166 lemmas word_minus_alt = word_arith_alts (4)
       
  1167 lemmas word_succ_alt = word_arith_alts (5)
       
  1168 lemmas word_pred_alt = word_arith_alts (6)
       
  1169 lemmas word_0_alt = word_arith_alts (7)
       
  1170 lemmas word_1_alt = word_arith_alts (8)
       
  1171 
       
  1172 subsection  "Transferring goals from words to ints"
       
  1173 
       
  1174 lemma word_ths:  
       
  1175   shows
       
  1176   word_succ_p1:   "word_succ a = a + 1" and
       
  1177   word_pred_m1:   "word_pred a = a - 1" and
       
  1178   word_pred_succ: "word_pred (word_succ a) = a" and
       
  1179   word_succ_pred: "word_succ (word_pred a) = a" and
       
  1180   word_mult_succ: "word_succ a * b = b + a * b"
       
  1181   by (rule word_uint.Abs_cases [of b],
       
  1182       rule word_uint.Abs_cases [of a],
       
  1183       simp add: pred_def succ_def add_commute mult_commute 
       
  1184                 ring_distribs new_word_of_int_homs)+
       
  1185 
       
  1186 lemmas uint_cong = arg_cong [where f = uint]
       
  1187 
       
  1188 lemmas uint_word_ariths = 
       
  1189   word_arith_alts [THEN trans [OF uint_cong int_word_uint], standard]
       
  1190 
       
  1191 lemmas uint_word_arith_bintrs = uint_word_ariths [folded bintrunc_mod2p]
       
  1192 
       
  1193 (* similar expressions for sint (arith operations) *)
       
  1194 lemmas sint_word_ariths = uint_word_arith_bintrs
       
  1195   [THEN uint_sint [symmetric, THEN trans],
       
  1196   unfolded uint_sint bintr_arith1s bintr_ariths 
       
  1197     len_gt_0 [THEN bin_sbin_eq_iff'] word_sbin.norm_Rep, standard]
       
  1198 
       
  1199 lemmas uint_div_alt = word_div_def
       
  1200   [THEN trans [OF uint_cong int_word_uint], standard]
       
  1201 lemmas uint_mod_alt = word_mod_def
       
  1202   [THEN trans [OF uint_cong int_word_uint], standard]
       
  1203 
       
  1204 lemma word_pred_0_n1: "word_pred 0 = word_of_int -1"
       
  1205   unfolding word_pred_def number_of_eq
       
  1206   by (simp add : pred_def word_no_wi)
       
  1207 
       
  1208 lemma word_pred_0_Min: "word_pred 0 = word_of_int Int.Min"
       
  1209   by (simp add: word_pred_0_n1 number_of_eq)
       
  1210 
       
  1211 lemma word_m1_Min: "- 1 = word_of_int Int.Min"
       
  1212   unfolding Min_def by (simp only: word_of_int_hom_syms)
       
  1213 
       
  1214 lemma succ_pred_no [simp]:
       
  1215   "word_succ (number_of bin) = number_of (Int.succ bin) & 
       
  1216     word_pred (number_of bin) = number_of (Int.pred bin)"
       
  1217   unfolding word_number_of_def by (simp add : new_word_of_int_homs)
       
  1218 
       
  1219 lemma word_sp_01 [simp] : 
       
  1220   "word_succ -1 = 0 & word_succ 0 = 1 & word_pred 0 = -1 & word_pred 1 = 0"
       
  1221   by (unfold word_0_no word_1_no) auto
       
  1222 
       
  1223 (* alternative approach to lifting arithmetic equalities *)
       
  1224 lemma word_of_int_Ex:
       
  1225   "\<exists>y. x = word_of_int y"
       
  1226   by (rule_tac x="uint x" in exI) simp
       
  1227 
       
  1228 lemma word_arith_eqs:
       
  1229   fixes a :: "'a::len0 word"
       
  1230   fixes b :: "'a::len0 word"
       
  1231   shows
       
  1232   word_add_0: "0 + a = a" and
       
  1233   word_add_0_right: "a + 0 = a" and
       
  1234   word_mult_1: "1 * a = a" and
       
  1235   word_mult_1_right: "a * 1 = a" and
       
  1236   word_add_commute: "a + b = b + a" and
       
  1237   word_add_assoc: "a + b + c = a + (b + c)" and
       
  1238   word_add_left_commute: "a + (b + c) = b + (a + c)" and
       
  1239   word_mult_commute: "a * b = b * a" and
       
  1240   word_mult_assoc: "a * b * c = a * (b * c)" and
       
  1241   word_mult_left_commute: "a * (b * c) = b * (a * c)" and
       
  1242   word_left_distrib: "(a + b) * c = a * c + b * c" and
       
  1243   word_right_distrib: "a * (b + c) = a * b + a * c" and
       
  1244   word_left_minus: "- a + a = 0" and
       
  1245   word_diff_0_right: "a - 0 = a" and
       
  1246   word_diff_self: "a - a = 0"
       
  1247   using word_of_int_Ex [of a] 
       
  1248         word_of_int_Ex [of b] 
       
  1249         word_of_int_Ex [of c]
       
  1250   by (auto simp: word_of_int_hom_syms [symmetric]
       
  1251                  zadd_0_right add_commute add_assoc add_left_commute
       
  1252                  mult_commute mult_assoc mult_left_commute
       
  1253                  left_distrib right_distrib)
       
  1254   
       
  1255 lemmas word_add_ac = word_add_commute word_add_assoc word_add_left_commute
       
  1256 lemmas word_mult_ac = word_mult_commute word_mult_assoc word_mult_left_commute
       
  1257   
       
  1258 lemmas word_plus_ac0 = word_add_0 word_add_0_right word_add_ac
       
  1259 lemmas word_times_ac1 = word_mult_1 word_mult_1_right word_mult_ac
       
  1260 
       
  1261 
       
  1262 subsection "Order on fixed-length words"
       
  1263 
       
  1264 lemma word_order_trans: "x <= y ==> y <= z ==> x <= (z :: 'a :: len0 word)"
       
  1265   unfolding word_le_def by auto
       
  1266 
       
  1267 lemma word_order_refl: "z <= (z :: 'a :: len0 word)"
       
  1268   unfolding word_le_def by auto
       
  1269 
       
  1270 lemma word_order_antisym: "x <= y ==> y <= x ==> x = (y :: 'a :: len0 word)"
       
  1271   unfolding word_le_def by (auto intro!: word_uint.Rep_eqD)
       
  1272 
       
  1273 lemma word_order_linear:
       
  1274   "y <= x | x <= (y :: 'a :: len0 word)"
       
  1275   unfolding word_le_def by auto
       
  1276 
       
  1277 lemma word_zero_le [simp] :
       
  1278   "0 <= (y :: 'a :: len0 word)"
       
  1279   unfolding word_le_def by auto
       
  1280   
       
  1281 instance word :: (len0) semigroup_add
       
  1282   by intro_classes (simp add: word_add_assoc)
       
  1283 
       
  1284 instance word :: (len0) linorder
       
  1285   by intro_classes (auto simp: word_less_def word_le_def)
       
  1286 
       
  1287 instance word :: (len0) ring
       
  1288   by intro_classes
       
  1289      (auto simp: word_arith_eqs word_diff_minus 
       
  1290                  word_diff_self [unfolded word_diff_minus])
       
  1291 
       
  1292 lemma word_m1_ge [simp] : "word_pred 0 >= y"
       
  1293   unfolding word_le_def
       
  1294   by (simp only : word_pred_0_n1 word_uint.eq_norm m1mod2k) auto
       
  1295 
       
  1296 lemmas word_n1_ge [simp]  = word_m1_ge [simplified word_sp_01]
       
  1297 
       
  1298 lemmas word_not_simps [simp] = 
       
  1299   word_zero_le [THEN leD] word_m1_ge [THEN leD] word_n1_ge [THEN leD]
       
  1300 
       
  1301 lemma word_gt_0: "0 < y = (0 ~= (y :: 'a :: len0 word))"
       
  1302   unfolding word_less_def by auto
       
  1303 
       
  1304 lemmas word_gt_0_no [simp] = word_gt_0 [of "number_of y", standard]
       
  1305 
       
  1306 lemma word_sless_alt: "(a <s b) == (sint a < sint b)"
       
  1307   unfolding word_sle_def word_sless_def
       
  1308   by (auto simp add: less_le)
       
  1309 
       
  1310 lemma word_le_nat_alt: "(a <= b) = (unat a <= unat b)"
       
  1311   unfolding unat_def word_le_def
       
  1312   by (rule nat_le_eq_zle [symmetric]) simp
       
  1313 
       
  1314 lemma word_less_nat_alt: "(a < b) = (unat a < unat b)"
       
  1315   unfolding unat_def word_less_alt
       
  1316   by (rule nat_less_eq_zless [symmetric]) simp
       
  1317   
       
  1318 lemma wi_less: 
       
  1319   "(word_of_int n < (word_of_int m :: 'a :: len0 word)) = 
       
  1320     (n mod 2 ^ len_of TYPE('a) < m mod 2 ^ len_of TYPE('a))"
       
  1321   unfolding word_less_alt by (simp add: word_uint.eq_norm)
       
  1322 
       
  1323 lemma wi_le: 
       
  1324   "(word_of_int n <= (word_of_int m :: 'a :: len0 word)) = 
       
  1325     (n mod 2 ^ len_of TYPE('a) <= m mod 2 ^ len_of TYPE('a))"
       
  1326   unfolding word_le_def by (simp add: word_uint.eq_norm)
       
  1327 
       
  1328 lemma udvd_nat_alt: "a udvd b = (EX n>=0. unat b = n * unat a)"
       
  1329   apply (unfold udvd_def)
       
  1330   apply safe
       
  1331    apply (simp add: unat_def nat_mult_distrib)
       
  1332   apply (simp add: uint_nat int_mult)
       
  1333   apply (rule exI)
       
  1334   apply safe
       
  1335    prefer 2
       
  1336    apply (erule notE)
       
  1337    apply (rule refl)
       
  1338   apply force
       
  1339   done
       
  1340 
       
  1341 lemma udvd_iff_dvd: "x udvd y <-> unat x dvd unat y"
       
  1342   unfolding dvd_def udvd_nat_alt by force
       
  1343 
       
  1344 lemmas unat_mono = word_less_nat_alt [THEN iffD1, standard]
       
  1345 
       
  1346 lemma word_zero_neq_one: "0 < len_of TYPE ('a :: len0) ==> (0 :: 'a word) ~= 1";
       
  1347   unfolding word_arith_wis
       
  1348   by (auto simp add: word_ubin.norm_eq_iff [symmetric] gr0_conv_Suc)
       
  1349 
       
  1350 lemmas lenw1_zero_neq_one = len_gt_0 [THEN word_zero_neq_one]
       
  1351 
       
  1352 lemma no_no [simp] : "number_of (number_of b) = number_of b"
       
  1353   by (simp add: number_of_eq)
       
  1354 
       
  1355 lemma unat_minus_one: "x ~= 0 ==> unat (x - 1) = unat x - 1"
       
  1356   apply (unfold unat_def)
       
  1357   apply (simp only: int_word_uint word_arith_alts rdmods)
       
  1358   apply (subgoal_tac "uint x >= 1")
       
  1359    prefer 2
       
  1360    apply (drule contrapos_nn)
       
  1361     apply (erule word_uint.Rep_inverse' [symmetric])
       
  1362    apply (insert uint_ge_0 [of x])[1]
       
  1363    apply arith
       
  1364   apply (rule box_equals)
       
  1365     apply (rule nat_diff_distrib)
       
  1366      prefer 2
       
  1367      apply assumption
       
  1368     apply simp
       
  1369    apply (subst mod_pos_pos_trivial)
       
  1370      apply arith
       
  1371     apply (insert uint_lt2p [of x])[1]
       
  1372     apply arith
       
  1373    apply (rule refl)
       
  1374   apply simp
       
  1375   done
       
  1376     
       
  1377 lemma measure_unat: "p ~= 0 ==> unat (p - 1) < unat p"
       
  1378   by (simp add: unat_minus_one) (simp add: unat_0_iff [symmetric])
       
  1379   
       
  1380 lemmas uint_add_ge0 [simp] =
       
  1381   add_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard]
       
  1382 lemmas uint_mult_ge0 [simp] =
       
  1383   mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard]
       
  1384 
       
  1385 lemma uint_sub_lt2p [simp]: 
       
  1386   "uint (x :: 'a :: len0 word) - uint (y :: 'b :: len0 word) < 
       
  1387     2 ^ len_of TYPE('a)"
       
  1388   using uint_ge_0 [of y] uint_lt2p [of x] by arith
       
  1389 
       
  1390 
       
  1391 subsection "Conditions for the addition (etc) of two words to overflow"
       
  1392 
       
  1393 lemma uint_add_lem: 
       
  1394   "(uint x + uint y < 2 ^ len_of TYPE('a)) = 
       
  1395     (uint (x + y :: 'a :: len0 word) = uint x + uint y)"
       
  1396   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
       
  1397 
       
  1398 lemma uint_mult_lem: 
       
  1399   "(uint x * uint y < 2 ^ len_of TYPE('a)) = 
       
  1400     (uint (x * y :: 'a :: len0 word) = uint x * uint y)"
       
  1401   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
       
  1402 
       
  1403 lemma uint_sub_lem: 
       
  1404   "(uint x >= uint y) = (uint (x - y) = uint x - uint y)"
       
  1405   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
       
  1406 
       
  1407 lemma uint_add_le: "uint (x + y) <= uint x + uint y"
       
  1408   unfolding uint_word_ariths by (auto simp: mod_add_if_z)
       
  1409 
       
  1410 lemma uint_sub_ge: "uint (x - y) >= uint x - uint y"
       
  1411   unfolding uint_word_ariths by (auto simp: mod_sub_if_z)
       
  1412 
       
  1413 lemmas uint_sub_if' =
       
  1414   trans [OF uint_word_ariths(1) mod_sub_if_z, simplified, standard]
       
  1415 lemmas uint_plus_if' =
       
  1416   trans [OF uint_word_ariths(2) mod_add_if_z, simplified, standard]
       
  1417 
       
  1418 
       
  1419 subsection {* Definition of uint\_arith *}
       
  1420 
       
  1421 lemma word_of_int_inverse:
       
  1422   "word_of_int r = a ==> 0 <= r ==> r < 2 ^ len_of TYPE('a) ==> 
       
  1423    uint (a::'a::len0 word) = r"
       
  1424   apply (erule word_uint.Abs_inverse' [rotated])
       
  1425   apply (simp add: uints_num)
       
  1426   done
       
  1427 
       
  1428 lemma uint_split:
       
  1429   fixes x::"'a::len0 word"
       
  1430   shows "P (uint x) = 
       
  1431          (ALL i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) --> P i)"
       
  1432   apply (fold word_int_case_def)
       
  1433   apply (auto dest!: word_of_int_inverse simp: int_word_uint int_mod_eq'
       
  1434               split: word_int_split)
       
  1435   done
       
  1436 
       
  1437 lemma uint_split_asm:
       
  1438   fixes x::"'a::len0 word"
       
  1439   shows "P (uint x) = 
       
  1440          (~(EX i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) & ~ P i))"
       
  1441   by (auto dest!: word_of_int_inverse 
       
  1442            simp: int_word_uint int_mod_eq'
       
  1443            split: uint_split)
       
  1444 
       
  1445 lemmas uint_splits = uint_split uint_split_asm
       
  1446 
       
  1447 lemmas uint_arith_simps = 
       
  1448   word_le_def word_less_alt
       
  1449   word_uint.Rep_inject [symmetric] 
       
  1450   uint_sub_if' uint_plus_if'
       
  1451 
       
  1452 (* use this to stop, eg, 2 ^ len_of TYPE (32) being simplified *)
       
  1453 lemma power_False_cong: "False ==> a ^ b = c ^ d" 
       
  1454   by auto
       
  1455 
       
  1456 (* uint_arith_tac: reduce to arithmetic on int, try to solve by arith *)
       
  1457 ML {*
       
  1458 fun uint_arith_ss_of ss = 
       
  1459   ss addsimps @{thms uint_arith_simps}
       
  1460      delsimps @{thms word_uint.Rep_inject}
       
  1461      addsplits @{thms split_if_asm} 
       
  1462      addcongs @{thms power_False_cong}
       
  1463 
       
  1464 fun uint_arith_tacs ctxt = 
       
  1465   let
       
  1466     fun arith_tac' n t =
       
  1467       Arith_Data.verbose_arith_tac ctxt n t
       
  1468         handle Cooper.COOPER _ => Seq.empty;
       
  1469     val cs = claset_of ctxt;
       
  1470     val ss = simpset_of ctxt;
       
  1471   in 
       
  1472     [ clarify_tac cs 1,
       
  1473       full_simp_tac (uint_arith_ss_of ss) 1,
       
  1474       ALLGOALS (full_simp_tac (HOL_ss addsplits @{thms uint_splits} 
       
  1475                                       addcongs @{thms power_False_cong})),
       
  1476       rewrite_goals_tac @{thms word_size}, 
       
  1477       ALLGOALS  (fn n => REPEAT (resolve_tac [allI, impI] n) THEN      
       
  1478                          REPEAT (etac conjE n) THEN
       
  1479                          REPEAT (dtac @{thm word_of_int_inverse} n 
       
  1480                                  THEN atac n 
       
  1481                                  THEN atac n)),
       
  1482       TRYALL arith_tac' ]
       
  1483   end
       
  1484 
       
  1485 fun uint_arith_tac ctxt = SELECT_GOAL (EVERY (uint_arith_tacs ctxt))
       
  1486 *}
       
  1487 
       
  1488 method_setup uint_arith = 
       
  1489   {* Scan.succeed (SIMPLE_METHOD' o uint_arith_tac) *}
       
  1490   "solving word arithmetic via integers and arith"
       
  1491 
       
  1492 
       
  1493 subsection "More on overflows and monotonicity"
       
  1494 
       
  1495 lemma no_plus_overflow_uint_size: 
       
  1496   "((x :: 'a :: len0 word) <= x + y) = (uint x + uint y < 2 ^ size x)"
       
  1497   unfolding word_size by uint_arith
       
  1498 
       
  1499 lemmas no_olen_add = no_plus_overflow_uint_size [unfolded word_size]
       
  1500 
       
  1501 lemma no_ulen_sub: "((x :: 'a :: len0 word) >= x - y) = (uint y <= uint x)"
       
  1502   by uint_arith
       
  1503 
       
  1504 lemma no_olen_add':
       
  1505   fixes x :: "'a::len0 word"
       
  1506   shows "(x \<le> y + x) = (uint y + uint x < 2 ^ len_of TYPE('a))"
       
  1507   by (simp add: word_add_ac add_ac no_olen_add)
       
  1508 
       
  1509 lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric], standard]
       
  1510 
       
  1511 lemmas uint_plus_simple_iff = trans [OF no_olen_add uint_add_lem, standard]
       
  1512 lemmas uint_plus_simple = uint_plus_simple_iff [THEN iffD1, standard]
       
  1513 lemmas uint_minus_simple_iff = trans [OF no_ulen_sub uint_sub_lem, standard]
       
  1514 lemmas uint_minus_simple_alt = uint_sub_lem [folded word_le_def]
       
  1515 lemmas word_sub_le_iff = no_ulen_sub [folded word_le_def]
       
  1516 lemmas word_sub_le = word_sub_le_iff [THEN iffD2, standard]
       
  1517 
       
  1518 lemma word_less_sub1: 
       
  1519   "(x :: 'a :: len word) ~= 0 ==> (1 < x) = (0 < x - 1)"
       
  1520   by uint_arith
       
  1521 
       
  1522 lemma word_le_sub1: 
       
  1523   "(x :: 'a :: len word) ~= 0 ==> (1 <= x) = (0 <= x - 1)"
       
  1524   by uint_arith
       
  1525 
       
  1526 lemma sub_wrap_lt: 
       
  1527   "((x :: 'a :: len0 word) < x - z) = (x < z)"
       
  1528   by uint_arith
       
  1529 
       
  1530 lemma sub_wrap: 
       
  1531   "((x :: 'a :: len0 word) <= x - z) = (z = 0 | x < z)"
       
  1532   by uint_arith
       
  1533 
       
  1534 lemma plus_minus_not_NULL_ab: 
       
  1535   "(x :: 'a :: len0 word) <= ab - c ==> c <= ab ==> c ~= 0 ==> x + c ~= 0"
       
  1536   by uint_arith
       
  1537 
       
  1538 lemma plus_minus_no_overflow_ab: 
       
  1539   "(x :: 'a :: len0 word) <= ab - c ==> c <= ab ==> x <= x + c" 
       
  1540   by uint_arith
       
  1541 
       
  1542 lemma le_minus': 
       
  1543   "(a :: 'a :: len0 word) + c <= b ==> a <= a + c ==> c <= b - a"
       
  1544   by uint_arith
       
  1545 
       
  1546 lemma le_plus': 
       
  1547   "(a :: 'a :: len0 word) <= b ==> c <= b - a ==> a + c <= b"
       
  1548   by uint_arith
       
  1549 
       
  1550 lemmas le_plus = le_plus' [rotated]
       
  1551 
       
  1552 lemmas le_minus = leD [THEN thin_rl, THEN le_minus', standard]
       
  1553 
       
  1554 lemma word_plus_mono_right: 
       
  1555   "(y :: 'a :: len0 word) <= z ==> x <= x + z ==> x + y <= x + z"
       
  1556   by uint_arith
       
  1557 
       
  1558 lemma word_less_minus_cancel: 
       
  1559   "y - x < z - x ==> x <= z ==> (y :: 'a :: len0 word) < z"
       
  1560   by uint_arith
       
  1561 
       
  1562 lemma word_less_minus_mono_left: 
       
  1563   "(y :: 'a :: len0 word) < z ==> x <= y ==> y - x < z - x"
       
  1564   by uint_arith
       
  1565 
       
  1566 lemma word_less_minus_mono:  
       
  1567   "a < c ==> d < b ==> a - b < a ==> c - d < c 
       
  1568   ==> a - b < c - (d::'a::len word)"
       
  1569   by uint_arith
       
  1570 
       
  1571 lemma word_le_minus_cancel: 
       
  1572   "y - x <= z - x ==> x <= z ==> (y :: 'a :: len0 word) <= z"
       
  1573   by uint_arith
       
  1574 
       
  1575 lemma word_le_minus_mono_left: 
       
  1576   "(y :: 'a :: len0 word) <= z ==> x <= y ==> y - x <= z - x"
       
  1577   by uint_arith
       
  1578 
       
  1579 lemma word_le_minus_mono:  
       
  1580   "a <= c ==> d <= b ==> a - b <= a ==> c - d <= c 
       
  1581   ==> a - b <= c - (d::'a::len word)"
       
  1582   by uint_arith
       
  1583 
       
  1584 lemma plus_le_left_cancel_wrap: 
       
  1585   "(x :: 'a :: len0 word) + y' < x ==> x + y < x ==> (x + y' < x + y) = (y' < y)"
       
  1586   by uint_arith
       
  1587 
       
  1588 lemma plus_le_left_cancel_nowrap: 
       
  1589   "(x :: 'a :: len0 word) <= x + y' ==> x <= x + y ==> 
       
  1590     (x + y' < x + y) = (y' < y)" 
       
  1591   by uint_arith
       
  1592 
       
  1593 lemma word_plus_mono_right2: 
       
  1594   "(a :: 'a :: len0 word) <= a + b ==> c <= b ==> a <= a + c"
       
  1595   by uint_arith
       
  1596 
       
  1597 lemma word_less_add_right: 
       
  1598   "(x :: 'a :: len0 word) < y - z ==> z <= y ==> x + z < y"
       
  1599   by uint_arith
       
  1600 
       
  1601 lemma word_less_sub_right: 
       
  1602   "(x :: 'a :: len0 word) < y + z ==> y <= x ==> x - y < z"
       
  1603   by uint_arith
       
  1604 
       
  1605 lemma word_le_plus_either: 
       
  1606   "(x :: 'a :: len0 word) <= y | x <= z ==> y <= y + z ==> x <= y + z"
       
  1607   by uint_arith
       
  1608 
       
  1609 lemma word_less_nowrapI: 
       
  1610   "(x :: 'a :: len0 word) < z - k ==> k <= z ==> 0 < k ==> x < x + k"
       
  1611   by uint_arith
       
  1612 
       
  1613 lemma inc_le: "(i :: 'a :: len word) < m ==> i + 1 <= m"
       
  1614   by uint_arith
       
  1615 
       
  1616 lemma inc_i: 
       
  1617   "(1 :: 'a :: len word) <= i ==> i < m ==> 1 <= (i + 1) & i + 1 <= m"
       
  1618   by uint_arith
       
  1619 
       
  1620 lemma udvd_incr_lem:
       
  1621   "up < uq ==> up = ua + n * uint K ==> 
       
  1622     uq = ua + n' * uint K ==> up + uint K <= uq"
       
  1623   apply clarsimp
       
  1624   apply (drule less_le_mult)
       
  1625   apply safe
       
  1626   done
       
  1627 
       
  1628 lemma udvd_incr': 
       
  1629   "p < q ==> uint p = ua + n * uint K ==> 
       
  1630     uint q = ua + n' * uint K ==> p + K <= q" 
       
  1631   apply (unfold word_less_alt word_le_def)
       
  1632   apply (drule (2) udvd_incr_lem)
       
  1633   apply (erule uint_add_le [THEN order_trans])
       
  1634   done
       
  1635 
       
  1636 lemma udvd_decr': 
       
  1637   "p < q ==> uint p = ua + n * uint K ==> 
       
  1638     uint q = ua + n' * uint K ==> p <= q - K"
       
  1639   apply (unfold word_less_alt word_le_def)
       
  1640   apply (drule (2) udvd_incr_lem)
       
  1641   apply (drule le_diff_eq [THEN iffD2])
       
  1642   apply (erule order_trans)
       
  1643   apply (rule uint_sub_ge)
       
  1644   done
       
  1645 
       
  1646 lemmas udvd_incr_lem0 = udvd_incr_lem [where ua=0, simplified]
       
  1647 lemmas udvd_incr0 = udvd_incr' [where ua=0, simplified]
       
  1648 lemmas udvd_decr0 = udvd_decr' [where ua=0, simplified]
       
  1649 
       
  1650 lemma udvd_minus_le': 
       
  1651   "xy < k ==> z udvd xy ==> z udvd k ==> xy <= k - z"
       
  1652   apply (unfold udvd_def)
       
  1653   apply clarify
       
  1654   apply (erule (2) udvd_decr0)
       
  1655   done
       
  1656 
       
  1657 ML {* Delsimprocs Numeral_Simprocs.cancel_factors *}
       
  1658 
       
  1659 lemma udvd_incr2_K: 
       
  1660   "p < a + s ==> a <= a + s ==> K udvd s ==> K udvd p - a ==> a <= p ==> 
       
  1661     0 < K ==> p <= p + K & p + K <= a + s"
       
  1662   apply (unfold udvd_def)
       
  1663   apply clarify
       
  1664   apply (simp add: uint_arith_simps split: split_if_asm)
       
  1665    prefer 2 
       
  1666    apply (insert uint_range' [of s])[1]
       
  1667    apply arith
       
  1668   apply (drule add_commute [THEN xtr1])
       
  1669   apply (simp add: diff_less_eq [symmetric])
       
  1670   apply (drule less_le_mult)
       
  1671    apply arith
       
  1672   apply simp
       
  1673   done
       
  1674 
       
  1675 ML {* Addsimprocs Numeral_Simprocs.cancel_factors *}
       
  1676 
       
  1677 (* links with rbl operations *)
       
  1678 lemma word_succ_rbl:
       
  1679   "to_bl w = bl ==> to_bl (word_succ w) = (rev (rbl_succ (rev bl)))"
       
  1680   apply (unfold word_succ_def)
       
  1681   apply clarify
       
  1682   apply (simp add: to_bl_of_bin)
       
  1683   apply (simp add: to_bl_def rbl_succ)
       
  1684   done
       
  1685 
       
  1686 lemma word_pred_rbl:
       
  1687   "to_bl w = bl ==> to_bl (word_pred w) = (rev (rbl_pred (rev bl)))"
       
  1688   apply (unfold word_pred_def)
       
  1689   apply clarify
       
  1690   apply (simp add: to_bl_of_bin)
       
  1691   apply (simp add: to_bl_def rbl_pred)
       
  1692   done
       
  1693 
       
  1694 lemma word_add_rbl:
       
  1695   "to_bl v = vbl ==> to_bl w = wbl ==> 
       
  1696     to_bl (v + w) = (rev (rbl_add (rev vbl) (rev wbl)))"
       
  1697   apply (unfold word_add_def)
       
  1698   apply clarify
       
  1699   apply (simp add: to_bl_of_bin)
       
  1700   apply (simp add: to_bl_def rbl_add)
       
  1701   done
       
  1702 
       
  1703 lemma word_mult_rbl:
       
  1704   "to_bl v = vbl ==> to_bl w = wbl ==> 
       
  1705     to_bl (v * w) = (rev (rbl_mult (rev vbl) (rev wbl)))"
       
  1706   apply (unfold word_mult_def)
       
  1707   apply clarify
       
  1708   apply (simp add: to_bl_of_bin)
       
  1709   apply (simp add: to_bl_def rbl_mult)
       
  1710   done
       
  1711 
       
  1712 lemma rtb_rbl_ariths:
       
  1713   "rev (to_bl w) = ys \<Longrightarrow> rev (to_bl (word_succ w)) = rbl_succ ys"
       
  1714 
       
  1715   "rev (to_bl w) = ys \<Longrightarrow> rev (to_bl (word_pred w)) = rbl_pred ys"
       
  1716 
       
  1717   "[| rev (to_bl v) = ys; rev (to_bl w) = xs |] 
       
  1718   ==> rev (to_bl (v * w)) = rbl_mult ys xs"
       
  1719 
       
  1720   "[| rev (to_bl v) = ys; rev (to_bl w) = xs |] 
       
  1721   ==> rev (to_bl (v + w)) = rbl_add ys xs"
       
  1722   by (auto simp: rev_swap [symmetric] word_succ_rbl 
       
  1723                  word_pred_rbl word_mult_rbl word_add_rbl)
       
  1724 
       
  1725 
       
  1726 subsection "Arithmetic type class instantiations"
       
  1727 
       
  1728 instance word :: (len0) comm_monoid_add ..
       
  1729 
       
  1730 instance word :: (len0) comm_monoid_mult
       
  1731   apply (intro_classes)
       
  1732    apply (simp add: word_mult_commute)
       
  1733   apply (simp add: word_mult_1)
       
  1734   done
       
  1735 
       
  1736 instance word :: (len0) comm_semiring 
       
  1737   by (intro_classes) (simp add : word_left_distrib)
       
  1738 
       
  1739 instance word :: (len0) ab_group_add ..
       
  1740 
       
  1741 instance word :: (len0) comm_ring ..
       
  1742 
       
  1743 instance word :: (len) comm_semiring_1 
       
  1744   by (intro_classes) (simp add: lenw1_zero_neq_one)
       
  1745 
       
  1746 instance word :: (len) comm_ring_1 ..
       
  1747 
       
  1748 instance word :: (len0) comm_semiring_0 ..
       
  1749 
       
  1750 instance word :: (len0) order ..
       
  1751 
       
  1752 (* note that iszero_def is only for class comm_semiring_1_cancel,
       
  1753    which requires word length >= 1, ie 'a :: len word *) 
       
  1754 lemma zero_bintrunc:
       
  1755   "iszero (number_of x :: 'a :: len word) = 
       
  1756     (bintrunc (len_of TYPE('a)) x = Int.Pls)"
       
  1757   apply (unfold iszero_def word_0_wi word_no_wi)
       
  1758   apply (rule word_ubin.norm_eq_iff [symmetric, THEN trans])
       
  1759   apply (simp add : Pls_def [symmetric])
       
  1760   done
       
  1761 
       
  1762 lemmas word_le_0_iff [simp] =
       
  1763   word_zero_le [THEN leD, THEN linorder_antisym_conv1]
       
  1764 
       
  1765 lemma word_of_nat: "of_nat n = word_of_int (int n)"
       
  1766   by (induct n) (auto simp add : word_of_int_hom_syms)
       
  1767 
       
  1768 lemma word_of_int: "of_int = word_of_int"
       
  1769   apply (rule ext)
       
  1770   apply (unfold of_int_def)
       
  1771   apply (rule contentsI)
       
  1772   apply safe
       
  1773   apply (simp_all add: word_of_nat word_of_int_homs)
       
  1774    defer
       
  1775    apply (rule Rep_Integ_ne [THEN nonemptyE])
       
  1776    apply (rule bexI)
       
  1777     prefer 2
       
  1778     apply assumption
       
  1779    apply (auto simp add: RI_eq_diff)
       
  1780   done
       
  1781 
       
  1782 lemma word_of_int_nat: 
       
  1783   "0 <= x ==> word_of_int x = of_nat (nat x)"
       
  1784   by (simp add: of_nat_nat word_of_int)
       
  1785 
       
  1786 lemma word_number_of_eq: 
       
  1787   "number_of w = (of_int w :: 'a :: len word)"
       
  1788   unfolding word_number_of_def word_of_int by auto
       
  1789 
       
  1790 instance word :: (len) number_ring
       
  1791   by (intro_classes) (simp add : word_number_of_eq)
       
  1792 
       
  1793 lemma iszero_word_no [simp] : 
       
  1794   "iszero (number_of bin :: 'a :: len word) = 
       
  1795     iszero (number_of (bintrunc (len_of TYPE('a)) bin) :: int)"
       
  1796   apply (simp add: zero_bintrunc number_of_is_id)
       
  1797   apply (unfold iszero_def Pls_def)
       
  1798   apply (rule refl)
       
  1799   done
       
  1800     
       
  1801 
       
  1802 subsection "Word and nat"
       
  1803 
       
  1804 lemma td_ext_unat':
       
  1805   "n = len_of TYPE ('a :: len) ==> 
       
  1806     td_ext (unat :: 'a word => nat) of_nat 
       
  1807     (unats n) (%i. i mod 2 ^ n)"
       
  1808   apply (unfold td_ext_def' unat_def word_of_nat unats_uints)
       
  1809   apply (auto intro!: imageI simp add : word_of_int_hom_syms)
       
  1810   apply (erule word_uint.Abs_inverse [THEN arg_cong])
       
  1811   apply (simp add: int_word_uint nat_mod_distrib nat_power_eq)
       
  1812   done
       
  1813 
       
  1814 lemmas td_ext_unat = refl [THEN td_ext_unat']
       
  1815 lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm, standard]
       
  1816 
       
  1817 interpretation word_unat:
       
  1818   td_ext "unat::'a::len word => nat" 
       
  1819          of_nat 
       
  1820          "unats (len_of TYPE('a::len))"
       
  1821          "%i. i mod 2 ^ len_of TYPE('a::len)"
       
  1822   by (rule td_ext_unat)
       
  1823 
       
  1824 lemmas td_unat = word_unat.td_thm
       
  1825 
       
  1826 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq]
       
  1827 
       
  1828 lemma unat_le: "y <= unat (z :: 'a :: len word) ==> y : unats (len_of TYPE ('a))"
       
  1829   apply (unfold unats_def)
       
  1830   apply clarsimp
       
  1831   apply (rule xtrans, rule unat_lt2p, assumption) 
       
  1832   done
       
  1833 
       
  1834 lemma word_nchotomy:
       
  1835   "ALL w. EX n. (w :: 'a :: len word) = of_nat n & n < 2 ^ len_of TYPE ('a)"
       
  1836   apply (rule allI)
       
  1837   apply (rule word_unat.Abs_cases)
       
  1838   apply (unfold unats_def)
       
  1839   apply auto
       
  1840   done
       
  1841 
       
  1842 lemma of_nat_eq:
       
  1843   fixes w :: "'a::len word"
       
  1844   shows "(of_nat n = w) = (\<exists>q. n = unat w + q * 2 ^ len_of TYPE('a))"
       
  1845   apply (rule trans)
       
  1846    apply (rule word_unat.inverse_norm)
       
  1847   apply (rule iffI)
       
  1848    apply (rule mod_eqD)
       
  1849    apply simp
       
  1850   apply clarsimp
       
  1851   done
       
  1852 
       
  1853 lemma of_nat_eq_size: 
       
  1854   "(of_nat n = w) = (EX q. n = unat w + q * 2 ^ size w)"
       
  1855   unfolding word_size by (rule of_nat_eq)
       
  1856 
       
  1857 lemma of_nat_0:
       
  1858   "(of_nat m = (0::'a::len word)) = (\<exists>q. m = q * 2 ^ len_of TYPE('a))"
       
  1859   by (simp add: of_nat_eq)
       
  1860 
       
  1861 lemmas of_nat_2p = mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]]
       
  1862 
       
  1863 lemma of_nat_gt_0: "of_nat k ~= 0 ==> 0 < k"
       
  1864   by (cases k) auto
       
  1865 
       
  1866 lemma of_nat_neq_0: 
       
  1867   "0 < k ==> k < 2 ^ len_of TYPE ('a :: len) ==> of_nat k ~= (0 :: 'a word)"
       
  1868   by (clarsimp simp add : of_nat_0)
       
  1869 
       
  1870 lemma Abs_fnat_hom_add:
       
  1871   "of_nat a + of_nat b = of_nat (a + b)"
       
  1872   by simp
       
  1873 
       
  1874 lemma Abs_fnat_hom_mult:
       
  1875   "of_nat a * of_nat b = (of_nat (a * b) :: 'a :: len word)"
       
  1876   by (simp add: word_of_nat word_of_int_mult_hom zmult_int)
       
  1877 
       
  1878 lemma Abs_fnat_hom_Suc:
       
  1879   "word_succ (of_nat a) = of_nat (Suc a)"
       
  1880   by (simp add: word_of_nat word_of_int_succ_hom add_ac)
       
  1881 
       
  1882 lemma Abs_fnat_hom_0: "(0::'a::len word) = of_nat 0"
       
  1883   by (simp add: word_of_nat word_0_wi)
       
  1884 
       
  1885 lemma Abs_fnat_hom_1: "(1::'a::len word) = of_nat (Suc 0)"
       
  1886   by (simp add: word_of_nat word_1_wi)
       
  1887 
       
  1888 lemmas Abs_fnat_homs = 
       
  1889   Abs_fnat_hom_add Abs_fnat_hom_mult Abs_fnat_hom_Suc 
       
  1890   Abs_fnat_hom_0 Abs_fnat_hom_1
       
  1891 
       
  1892 lemma word_arith_nat_add:
       
  1893   "a + b = of_nat (unat a + unat b)" 
       
  1894   by simp
       
  1895 
       
  1896 lemma word_arith_nat_mult:
       
  1897   "a * b = of_nat (unat a * unat b)"
       
  1898   by (simp add: Abs_fnat_hom_mult [symmetric])
       
  1899     
       
  1900 lemma word_arith_nat_Suc:
       
  1901   "word_succ a = of_nat (Suc (unat a))"
       
  1902   by (subst Abs_fnat_hom_Suc [symmetric]) simp
       
  1903 
       
  1904 lemma word_arith_nat_div:
       
  1905   "a div b = of_nat (unat a div unat b)"
       
  1906   by (simp add: word_div_def word_of_nat zdiv_int uint_nat)
       
  1907 
       
  1908 lemma word_arith_nat_mod:
       
  1909   "a mod b = of_nat (unat a mod unat b)"
       
  1910   by (simp add: word_mod_def word_of_nat zmod_int uint_nat)
       
  1911 
       
  1912 lemmas word_arith_nat_defs =
       
  1913   word_arith_nat_add word_arith_nat_mult
       
  1914   word_arith_nat_Suc Abs_fnat_hom_0
       
  1915   Abs_fnat_hom_1 word_arith_nat_div
       
  1916   word_arith_nat_mod 
       
  1917 
       
  1918 lemmas unat_cong = arg_cong [where f = "unat"]
       
  1919   
       
  1920 lemmas unat_word_ariths = word_arith_nat_defs
       
  1921   [THEN trans [OF unat_cong unat_of_nat], standard]
       
  1922 
       
  1923 lemmas word_sub_less_iff = word_sub_le_iff
       
  1924   [simplified linorder_not_less [symmetric], simplified]
       
  1925 
       
  1926 lemma unat_add_lem: 
       
  1927   "(unat x + unat y < 2 ^ len_of TYPE('a)) = 
       
  1928     (unat (x + y :: 'a :: len word) = unat x + unat y)"
       
  1929   unfolding unat_word_ariths
       
  1930   by (auto intro!: trans [OF _ nat_mod_lem])
       
  1931 
       
  1932 lemma unat_mult_lem: 
       
  1933   "(unat x * unat y < 2 ^ len_of TYPE('a)) = 
       
  1934     (unat (x * y :: 'a :: len word) = unat x * unat y)"
       
  1935   unfolding unat_word_ariths
       
  1936   by (auto intro!: trans [OF _ nat_mod_lem])
       
  1937 
       
  1938 lemmas unat_plus_if' = 
       
  1939   trans [OF unat_word_ariths(1) mod_nat_add, simplified, standard]
       
  1940 
       
  1941 lemma le_no_overflow: 
       
  1942   "x <= b ==> a <= a + b ==> x <= a + (b :: 'a :: len0 word)"
       
  1943   apply (erule order_trans)
       
  1944   apply (erule olen_add_eqv [THEN iffD1])
       
  1945   done
       
  1946 
       
  1947 lemmas un_ui_le = trans 
       
  1948   [OF word_le_nat_alt [symmetric] 
       
  1949       word_le_def, 
       
  1950    standard]
       
  1951 
       
  1952 lemma unat_sub_if_size:
       
  1953   "unat (x - y) = (if unat y <= unat x 
       
  1954    then unat x - unat y 
       
  1955    else unat x + 2 ^ size x - unat y)"
       
  1956   apply (unfold word_size)
       
  1957   apply (simp add: un_ui_le)
       
  1958   apply (auto simp add: unat_def uint_sub_if')
       
  1959    apply (rule nat_diff_distrib)
       
  1960     prefer 3
       
  1961     apply (simp add: algebra_simps)
       
  1962     apply (rule nat_diff_distrib [THEN trans])
       
  1963       prefer 3
       
  1964       apply (subst nat_add_distrib)
       
  1965         prefer 3
       
  1966         apply (simp add: nat_power_eq)
       
  1967        apply auto
       
  1968   apply uint_arith
       
  1969   done
       
  1970 
       
  1971 lemmas unat_sub_if' = unat_sub_if_size [unfolded word_size]
       
  1972 
       
  1973 lemma unat_div: "unat ((x :: 'a :: len word) div y) = unat x div unat y"
       
  1974   apply (simp add : unat_word_ariths)
       
  1975   apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
       
  1976   apply (rule div_le_dividend)
       
  1977   done
       
  1978 
       
  1979 lemma unat_mod: "unat ((x :: 'a :: len word) mod y) = unat x mod unat y"
       
  1980   apply (clarsimp simp add : unat_word_ariths)
       
  1981   apply (cases "unat y")
       
  1982    prefer 2
       
  1983    apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
       
  1984    apply (rule mod_le_divisor)
       
  1985    apply auto
       
  1986   done
       
  1987 
       
  1988 lemma uint_div: "uint ((x :: 'a :: len word) div y) = uint x div uint y"
       
  1989   unfolding uint_nat by (simp add : unat_div zdiv_int)
       
  1990 
       
  1991 lemma uint_mod: "uint ((x :: 'a :: len word) mod y) = uint x mod uint y"
       
  1992   unfolding uint_nat by (simp add : unat_mod zmod_int)
       
  1993 
       
  1994 
       
  1995 subsection {* Definition of unat\_arith tactic *}
       
  1996 
       
  1997 lemma unat_split:
       
  1998   fixes x::"'a::len word"
       
  1999   shows "P (unat x) = 
       
  2000          (ALL n. of_nat n = x & n < 2^len_of TYPE('a) --> P n)"
       
  2001   by (auto simp: unat_of_nat)
       
  2002 
       
  2003 lemma unat_split_asm:
       
  2004   fixes x::"'a::len word"
       
  2005   shows "P (unat x) = 
       
  2006          (~(EX n. of_nat n = x & n < 2^len_of TYPE('a) & ~ P n))"
       
  2007   by (auto simp: unat_of_nat)
       
  2008 
       
  2009 lemmas of_nat_inverse = 
       
  2010   word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified]
       
  2011 
       
  2012 lemmas unat_splits = unat_split unat_split_asm
       
  2013 
       
  2014 lemmas unat_arith_simps =
       
  2015   word_le_nat_alt word_less_nat_alt
       
  2016   word_unat.Rep_inject [symmetric]
       
  2017   unat_sub_if' unat_plus_if' unat_div unat_mod
       
  2018 
       
  2019 (* unat_arith_tac: tactic to reduce word arithmetic to nat, 
       
  2020    try to solve via arith *)
       
  2021 ML {*
       
  2022 fun unat_arith_ss_of ss = 
       
  2023   ss addsimps @{thms unat_arith_simps}
       
  2024      delsimps @{thms word_unat.Rep_inject}
       
  2025      addsplits @{thms split_if_asm}
       
  2026      addcongs @{thms power_False_cong}
       
  2027 
       
  2028 fun unat_arith_tacs ctxt =   
       
  2029   let
       
  2030     fun arith_tac' n t =
       
  2031       Arith_Data.verbose_arith_tac ctxt n t
       
  2032         handle Cooper.COOPER _ => Seq.empty;
       
  2033     val cs = claset_of ctxt;
       
  2034     val ss = simpset_of ctxt;
       
  2035   in 
       
  2036     [ clarify_tac cs 1,
       
  2037       full_simp_tac (unat_arith_ss_of ss) 1,
       
  2038       ALLGOALS (full_simp_tac (HOL_ss addsplits @{thms unat_splits} 
       
  2039                                        addcongs @{thms power_False_cong})),
       
  2040       rewrite_goals_tac @{thms word_size}, 
       
  2041       ALLGOALS  (fn n => REPEAT (resolve_tac [allI, impI] n) THEN      
       
  2042                          REPEAT (etac conjE n) THEN
       
  2043                          REPEAT (dtac @{thm of_nat_inverse} n THEN atac n)),
       
  2044       TRYALL arith_tac' ] 
       
  2045   end
       
  2046 
       
  2047 fun unat_arith_tac ctxt = SELECT_GOAL (EVERY (unat_arith_tacs ctxt))
       
  2048 *}
       
  2049 
       
  2050 method_setup unat_arith = 
       
  2051   {* Scan.succeed (SIMPLE_METHOD' o unat_arith_tac) *}
       
  2052   "solving word arithmetic via natural numbers and arith"
       
  2053 
       
  2054 lemma no_plus_overflow_unat_size: 
       
  2055   "((x :: 'a :: len word) <= x + y) = (unat x + unat y < 2 ^ size x)" 
       
  2056   unfolding word_size by unat_arith
       
  2057 
       
  2058 lemmas no_olen_add_nat = no_plus_overflow_unat_size [unfolded word_size]
       
  2059 
       
  2060 lemmas unat_plus_simple = trans [OF no_olen_add_nat unat_add_lem, standard]
       
  2061 
       
  2062 lemma word_div_mult: 
       
  2063   "(0 :: 'a :: len word) < y ==> unat x * unat y < 2 ^ len_of TYPE('a) ==> 
       
  2064     x * y div y = x"
       
  2065   apply unat_arith
       
  2066   apply clarsimp
       
  2067   apply (subst unat_mult_lem [THEN iffD1])
       
  2068   apply auto
       
  2069   done
       
  2070 
       
  2071 lemma div_lt': "(i :: 'a :: len word) <= k div x ==> 
       
  2072     unat i * unat x < 2 ^ len_of TYPE('a)"
       
  2073   apply unat_arith
       
  2074   apply clarsimp
       
  2075   apply (drule mult_le_mono1)
       
  2076   apply (erule order_le_less_trans)
       
  2077   apply (rule xtr7 [OF unat_lt2p div_mult_le])
       
  2078   done
       
  2079 
       
  2080 lemmas div_lt'' = order_less_imp_le [THEN div_lt']
       
  2081 
       
  2082 lemma div_lt_mult: "(i :: 'a :: len word) < k div x ==> 0 < x ==> i * x < k"
       
  2083   apply (frule div_lt'' [THEN unat_mult_lem [THEN iffD1]])
       
  2084   apply (simp add: unat_arith_simps)
       
  2085   apply (drule (1) mult_less_mono1)
       
  2086   apply (erule order_less_le_trans)
       
  2087   apply (rule div_mult_le)
       
  2088   done
       
  2089 
       
  2090 lemma div_le_mult: 
       
  2091   "(i :: 'a :: len word) <= k div x ==> 0 < x ==> i * x <= k"
       
  2092   apply (frule div_lt' [THEN unat_mult_lem [THEN iffD1]])
       
  2093   apply (simp add: unat_arith_simps)
       
  2094   apply (drule mult_le_mono1)
       
  2095   apply (erule order_trans)
       
  2096   apply (rule div_mult_le)
       
  2097   done
       
  2098 
       
  2099 lemma div_lt_uint': 
       
  2100   "(i :: 'a :: len word) <= k div x ==> uint i * uint x < 2 ^ len_of TYPE('a)"
       
  2101   apply (unfold uint_nat)
       
  2102   apply (drule div_lt')
       
  2103   apply (simp add: zmult_int zless_nat_eq_int_zless [symmetric] 
       
  2104                    nat_power_eq)
       
  2105   done
       
  2106 
       
  2107 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint']
       
  2108 
       
  2109 lemma word_le_exists': 
       
  2110   "(x :: 'a :: len0 word) <= y ==> 
       
  2111     (EX z. y = x + z & uint x + uint z < 2 ^ len_of TYPE('a))"
       
  2112   apply (rule exI)
       
  2113   apply (rule conjI)
       
  2114   apply (rule zadd_diff_inverse)
       
  2115   apply uint_arith
       
  2116   done
       
  2117 
       
  2118 lemmas plus_minus_not_NULL = order_less_imp_le [THEN plus_minus_not_NULL_ab]
       
  2119 
       
  2120 lemmas plus_minus_no_overflow =
       
  2121   order_less_imp_le [THEN plus_minus_no_overflow_ab]
       
  2122   
       
  2123 lemmas mcs = word_less_minus_cancel word_less_minus_mono_left
       
  2124   word_le_minus_cancel word_le_minus_mono_left
       
  2125 
       
  2126 lemmas word_l_diffs = mcs [where y = "w + x", unfolded add_diff_cancel, standard]
       
  2127 lemmas word_diff_ls = mcs [where z = "w + x", unfolded add_diff_cancel, standard]
       
  2128 lemmas word_plus_mcs = word_diff_ls 
       
  2129   [where y = "v + x", unfolded add_diff_cancel, standard]
       
  2130 
       
  2131 lemmas le_unat_uoi = unat_le [THEN word_unat.Abs_inverse]
       
  2132 
       
  2133 lemmas thd = refl [THEN [2] split_div_lemma [THEN iffD2], THEN conjunct1]
       
  2134 
       
  2135 lemma thd1:
       
  2136   "a div b * b \<le> (a::nat)"
       
  2137   using gt_or_eq_0 [of b]
       
  2138   apply (rule disjE)
       
  2139    apply (erule xtr4 [OF thd mult_commute])
       
  2140   apply clarsimp
       
  2141   done
       
  2142 
       
  2143 lemmas uno_simps [THEN le_unat_uoi, standard] =
       
  2144   mod_le_divisor div_le_dividend thd1 
       
  2145 
       
  2146 lemma word_mod_div_equality:
       
  2147   "(n div b) * b + (n mod b) = (n :: 'a :: len word)"
       
  2148   apply (unfold word_less_nat_alt word_arith_nat_defs)
       
  2149   apply (cut_tac y="unat b" in gt_or_eq_0)
       
  2150   apply (erule disjE)
       
  2151    apply (simp add: mod_div_equality uno_simps)
       
  2152   apply simp
       
  2153   done
       
  2154 
       
  2155 lemma word_div_mult_le: "a div b * b <= (a::'a::len word)"
       
  2156   apply (unfold word_le_nat_alt word_arith_nat_defs)
       
  2157   apply (cut_tac y="unat b" in gt_or_eq_0)
       
  2158   apply (erule disjE)
       
  2159    apply (simp add: div_mult_le uno_simps)
       
  2160   apply simp
       
  2161   done
       
  2162 
       
  2163 lemma word_mod_less_divisor: "0 < n ==> m mod n < (n :: 'a :: len word)"
       
  2164   apply (simp only: word_less_nat_alt word_arith_nat_defs)
       
  2165   apply (clarsimp simp add : uno_simps)
       
  2166   done
       
  2167 
       
  2168 lemma word_of_int_power_hom: 
       
  2169   "word_of_int a ^ n = (word_of_int (a ^ n) :: 'a :: len word)"
       
  2170   by (induct n) (simp_all add : word_of_int_hom_syms power_Suc)
       
  2171 
       
  2172 lemma word_arith_power_alt: 
       
  2173   "a ^ n = (word_of_int (uint a ^ n) :: 'a :: len word)"
       
  2174   by (simp add : word_of_int_power_hom [symmetric])
       
  2175 
       
  2176 lemma of_bl_length_less: 
       
  2177   "length x = k ==> k < len_of TYPE('a) ==> (of_bl x :: 'a :: len word) < 2 ^ k"
       
  2178   apply (unfold of_bl_no [unfolded word_number_of_def]
       
  2179                 word_less_alt word_number_of_alt)
       
  2180   apply safe
       
  2181   apply (simp (no_asm) add: word_of_int_power_hom word_uint.eq_norm 
       
  2182                        del: word_of_int_bin)
       
  2183   apply (simp add: mod_pos_pos_trivial)
       
  2184   apply (subst mod_pos_pos_trivial)
       
  2185     apply (rule bl_to_bin_ge0)
       
  2186    apply (rule order_less_trans)
       
  2187     apply (rule bl_to_bin_lt2p)
       
  2188    apply simp
       
  2189   apply (rule bl_to_bin_lt2p)    
       
  2190   done
       
  2191 
       
  2192 
       
  2193 subsection "Cardinality, finiteness of set of words"
       
  2194 
       
  2195 lemmas card_lessThan' = card_lessThan [unfolded lessThan_def]
       
  2196 
       
  2197 lemmas card_eq = word_unat.Abs_inj_on [THEN card_image,
       
  2198   unfolded word_unat.image, unfolded unats_def, standard]
       
  2199 
       
  2200 lemmas card_word = trans [OF card_eq card_lessThan', standard]
       
  2201 
       
  2202 lemma finite_word_UNIV: "finite (UNIV :: 'a :: len word set)"
       
  2203 apply (rule contrapos_np)
       
  2204  prefer 2
       
  2205  apply (erule card_infinite)
       
  2206 apply (simp add: card_word)
       
  2207 done
       
  2208 
       
  2209 lemma card_word_size: 
       
  2210   "card (UNIV :: 'a :: len word set) = (2 ^ size (x :: 'a word))"
       
  2211 unfolding word_size by (rule card_word)
       
  2212 
       
  2213 
       
  2214 subsection {* Bitwise Operations on Words *}
       
  2215 
       
  2216 lemmas bin_log_bintrs = bin_trunc_not bin_trunc_xor bin_trunc_and bin_trunc_or
       
  2217   
       
  2218 (* following definitions require both arithmetic and bit-wise word operations *)
       
  2219 
       
  2220 (* to get word_no_log_defs from word_log_defs, using bin_log_bintrs *)
       
  2221 lemmas wils1 = bin_log_bintrs [THEN word_ubin.norm_eq_iff [THEN iffD1],
       
  2222   folded word_ubin.eq_norm, THEN eq_reflection, standard]
       
  2223 
       
  2224 (* the binary operations only *)
       
  2225 lemmas word_log_binary_defs = 
       
  2226   word_and_def word_or_def word_xor_def
       
  2227 
       
  2228 lemmas word_no_log_defs [simp] = 
       
  2229   word_not_def  [where a="number_of a", 
       
  2230                  unfolded word_no_wi wils1, folded word_no_wi, standard]
       
  2231   word_log_binary_defs [where a="number_of a" and b="number_of b",
       
  2232                         unfolded word_no_wi wils1, folded word_no_wi, standard]
       
  2233 
       
  2234 lemmas word_wi_log_defs = word_no_log_defs [unfolded word_no_wi]
       
  2235 
       
  2236 lemma uint_or: "uint (x OR y) = (uint x) OR (uint y)"
       
  2237   by (simp add: word_or_def word_no_wi [symmetric] number_of_is_id
       
  2238                 bin_trunc_ao(2) [symmetric])
       
  2239 
       
  2240 lemma uint_and: "uint (x AND y) = (uint x) AND (uint y)"
       
  2241   by (simp add: word_and_def number_of_is_id word_no_wi [symmetric]
       
  2242                 bin_trunc_ao(1) [symmetric]) 
       
  2243 
       
  2244 lemma word_ops_nth_size:
       
  2245   "n < size (x::'a::len0 word) ==> 
       
  2246     (x OR y) !! n = (x !! n | y !! n) & 
       
  2247     (x AND y) !! n = (x !! n & y !! n) & 
       
  2248     (x XOR y) !! n = (x !! n ~= y !! n) & 
       
  2249     (NOT x) !! n = (~ x !! n)"
       
  2250   unfolding word_size word_no_wi word_test_bit_def word_log_defs
       
  2251   by (clarsimp simp add : word_ubin.eq_norm nth_bintr bin_nth_ops)
       
  2252 
       
  2253 lemma word_ao_nth:
       
  2254   fixes x :: "'a::len0 word"
       
  2255   shows "(x OR y) !! n = (x !! n | y !! n) & 
       
  2256          (x AND y) !! n = (x !! n & y !! n)"
       
  2257   apply (cases "n < size x")
       
  2258    apply (drule_tac y = "y" in word_ops_nth_size)
       
  2259    apply simp
       
  2260   apply (simp add : test_bit_bin word_size)
       
  2261   done
       
  2262 
       
  2263 (* get from commutativity, associativity etc of int_and etc
       
  2264   to same for word_and etc *)
       
  2265 
       
  2266 lemmas bwsimps = 
       
  2267   word_of_int_homs(2) 
       
  2268   word_0_wi_Pls
       
  2269   word_m1_wi_Min
       
  2270   word_wi_log_defs
       
  2271 
       
  2272 lemma word_bw_assocs:
       
  2273   fixes x :: "'a::len0 word"
       
  2274   shows
       
  2275   "(x AND y) AND z = x AND y AND z"
       
  2276   "(x OR y) OR z = x OR y OR z"
       
  2277   "(x XOR y) XOR z = x XOR y XOR z"
       
  2278   using word_of_int_Ex [where x=x] 
       
  2279         word_of_int_Ex [where x=y] 
       
  2280         word_of_int_Ex [where x=z]
       
  2281   by (auto simp: bwsimps bbw_assocs)
       
  2282   
       
  2283 lemma word_bw_comms:
       
  2284   fixes x :: "'a::len0 word"
       
  2285   shows
       
  2286   "x AND y = y AND x"
       
  2287   "x OR y = y OR x"
       
  2288   "x XOR y = y XOR x"
       
  2289   using word_of_int_Ex [where x=x] 
       
  2290         word_of_int_Ex [where x=y] 
       
  2291   by (auto simp: bwsimps bin_ops_comm)
       
  2292   
       
  2293 lemma word_bw_lcs:
       
  2294   fixes x :: "'a::len0 word"
       
  2295   shows
       
  2296   "y AND x AND z = x AND y AND z"
       
  2297   "y OR x OR z = x OR y OR z"
       
  2298   "y XOR x XOR z = x XOR y XOR z"
       
  2299   using word_of_int_Ex [where x=x] 
       
  2300         word_of_int_Ex [where x=y] 
       
  2301         word_of_int_Ex [where x=z]
       
  2302   by (auto simp: bwsimps)
       
  2303 
       
  2304 lemma word_log_esimps [simp]:
       
  2305   fixes x :: "'a::len0 word"
       
  2306   shows
       
  2307   "x AND 0 = 0"
       
  2308   "x AND -1 = x"
       
  2309   "x OR 0 = x"
       
  2310   "x OR -1 = -1"
       
  2311   "x XOR 0 = x"
       
  2312   "x XOR -1 = NOT x"
       
  2313   "0 AND x = 0"
       
  2314   "-1 AND x = x"
       
  2315   "0 OR x = x"
       
  2316   "-1 OR x = -1"
       
  2317   "0 XOR x = x"
       
  2318   "-1 XOR x = NOT x"
       
  2319   using word_of_int_Ex [where x=x] 
       
  2320   by (auto simp: bwsimps)
       
  2321 
       
  2322 lemma word_not_dist:
       
  2323   fixes x :: "'a::len0 word"
       
  2324   shows
       
  2325   "NOT (x OR y) = NOT x AND NOT y"
       
  2326   "NOT (x AND y) = NOT x OR NOT y"
       
  2327   using word_of_int_Ex [where x=x] 
       
  2328         word_of_int_Ex [where x=y] 
       
  2329   by (auto simp: bwsimps bbw_not_dist)
       
  2330 
       
  2331 lemma word_bw_same:
       
  2332   fixes x :: "'a::len0 word"
       
  2333   shows
       
  2334   "x AND x = x"
       
  2335   "x OR x = x"
       
  2336   "x XOR x = 0"
       
  2337   using word_of_int_Ex [where x=x] 
       
  2338   by (auto simp: bwsimps)
       
  2339 
       
  2340 lemma word_ao_absorbs [simp]:
       
  2341   fixes x :: "'a::len0 word"
       
  2342   shows
       
  2343   "x AND (y OR x) = x"
       
  2344   "x OR y AND x = x"
       
  2345   "x AND (x OR y) = x"
       
  2346   "y AND x OR x = x"
       
  2347   "(y OR x) AND x = x"
       
  2348   "x OR x AND y = x"
       
  2349   "(x OR y) AND x = x"
       
  2350   "x AND y OR x = x"
       
  2351   using word_of_int_Ex [where x=x] 
       
  2352         word_of_int_Ex [where x=y] 
       
  2353   by (auto simp: bwsimps)
       
  2354 
       
  2355 lemma word_not_not [simp]:
       
  2356   "NOT NOT (x::'a::len0 word) = x"
       
  2357   using word_of_int_Ex [where x=x] 
       
  2358   by (auto simp: bwsimps)
       
  2359 
       
  2360 lemma word_ao_dist:
       
  2361   fixes x :: "'a::len0 word"
       
  2362   shows "(x OR y) AND z = x AND z OR y AND z"
       
  2363   using word_of_int_Ex [where x=x] 
       
  2364         word_of_int_Ex [where x=y] 
       
  2365         word_of_int_Ex [where x=z]   
       
  2366   by (auto simp: bwsimps bbw_ao_dist simp del: bin_ops_comm)
       
  2367 
       
  2368 lemma word_oa_dist:
       
  2369   fixes x :: "'a::len0 word"
       
  2370   shows "x AND y OR z = (x OR z) AND (y OR z)"
       
  2371   using word_of_int_Ex [where x=x] 
       
  2372         word_of_int_Ex [where x=y] 
       
  2373         word_of_int_Ex [where x=z]   
       
  2374   by (auto simp: bwsimps bbw_oa_dist simp del: bin_ops_comm)
       
  2375 
       
  2376 lemma word_add_not [simp]: 
       
  2377   fixes x :: "'a::len0 word"
       
  2378   shows "x + NOT x = -1"
       
  2379   using word_of_int_Ex [where x=x] 
       
  2380   by (auto simp: bwsimps bin_add_not)
       
  2381 
       
  2382 lemma word_plus_and_or [simp]:
       
  2383   fixes x :: "'a::len0 word"
       
  2384   shows "(x AND y) + (x OR y) = x + y"
       
  2385   using word_of_int_Ex [where x=x] 
       
  2386         word_of_int_Ex [where x=y] 
       
  2387   by (auto simp: bwsimps plus_and_or)
       
  2388 
       
  2389 lemma leoa:   
       
  2390   fixes x :: "'a::len0 word"
       
  2391   shows "(w = (x OR y)) ==> (y = (w AND y))" by auto
       
  2392 lemma leao: 
       
  2393   fixes x' :: "'a::len0 word"
       
  2394   shows "(w' = (x' AND y')) ==> (x' = (x' OR w'))" by auto 
       
  2395 
       
  2396 lemmas word_ao_equiv = leao [COMP leoa [COMP iffI]]
       
  2397 
       
  2398 lemma le_word_or2: "x <= x OR (y::'a::len0 word)"
       
  2399   unfolding word_le_def uint_or
       
  2400   by (auto intro: le_int_or) 
       
  2401 
       
  2402 lemmas le_word_or1 = xtr3 [OF word_bw_comms (2) le_word_or2, standard]
       
  2403 lemmas word_and_le1 =
       
  2404   xtr3 [OF word_ao_absorbs (4) [symmetric] le_word_or2, standard]
       
  2405 lemmas word_and_le2 =
       
  2406   xtr3 [OF word_ao_absorbs (8) [symmetric] le_word_or2, standard]
       
  2407 
       
  2408 lemma bl_word_not: "to_bl (NOT w) = map Not (to_bl w)" 
       
  2409   unfolding to_bl_def word_log_defs
       
  2410   by (simp add: bl_not_bin number_of_is_id word_no_wi [symmetric] bin_to_bl_def[symmetric])
       
  2411 
       
  2412 lemma bl_word_xor: "to_bl (v XOR w) = map2 op ~= (to_bl v) (to_bl w)" 
       
  2413   unfolding to_bl_def word_log_defs bl_xor_bin
       
  2414   by (simp add: number_of_is_id word_no_wi [symmetric])
       
  2415 
       
  2416 lemma bl_word_or: "to_bl (v OR w) = map2 op | (to_bl v) (to_bl w)" 
       
  2417   unfolding to_bl_def word_log_defs
       
  2418   by (simp add: bl_or_bin number_of_is_id word_no_wi [symmetric])
       
  2419 
       
  2420 lemma bl_word_and: "to_bl (v AND w) = map2 op & (to_bl v) (to_bl w)" 
       
  2421   unfolding to_bl_def word_log_defs
       
  2422   by (simp add: bl_and_bin number_of_is_id word_no_wi [symmetric])
       
  2423 
       
  2424 lemma word_lsb_alt: "lsb (w::'a::len0 word) = test_bit w 0"
       
  2425   by (auto simp: word_test_bit_def word_lsb_def)
       
  2426 
       
  2427 lemma word_lsb_1_0: "lsb (1::'a::len word) & ~ lsb (0::'b::len0 word)"
       
  2428   unfolding word_lsb_def word_1_no word_0_no by auto
       
  2429 
       
  2430 lemma word_lsb_last: "lsb (w::'a::len word) = last (to_bl w)"
       
  2431   apply (unfold word_lsb_def uint_bl bin_to_bl_def) 
       
  2432   apply (rule_tac bin="uint w" in bin_exhaust)
       
  2433   apply (cases "size w")
       
  2434    apply auto
       
  2435    apply (auto simp add: bin_to_bl_aux_alt)
       
  2436   done
       
  2437 
       
  2438 lemma word_lsb_int: "lsb w = (uint w mod 2 = 1)"
       
  2439   unfolding word_lsb_def bin_last_mod by auto
       
  2440 
       
  2441 lemma word_msb_sint: "msb w = (sint w < 0)" 
       
  2442   unfolding word_msb_def
       
  2443   by (simp add : sign_Min_lt_0 number_of_is_id)
       
  2444   
       
  2445 lemma word_msb_no': 
       
  2446   "w = number_of bin ==> msb (w::'a::len word) = bin_nth bin (size w - 1)"
       
  2447   unfolding word_msb_def word_number_of_def
       
  2448   by (clarsimp simp add: word_sbin.eq_norm word_size bin_sign_lem)
       
  2449 
       
  2450 lemmas word_msb_no = refl [THEN word_msb_no', unfolded word_size]
       
  2451 
       
  2452 lemma word_msb_nth': "msb (w::'a::len word) = bin_nth (uint w) (size w - 1)"
       
  2453   apply (unfold word_size)
       
  2454   apply (rule trans [OF _ word_msb_no])
       
  2455   apply (simp add : word_number_of_def)
       
  2456   done
       
  2457 
       
  2458 lemmas word_msb_nth = word_msb_nth' [unfolded word_size]
       
  2459 
       
  2460 lemma word_msb_alt: "msb (w::'a::len word) = hd (to_bl w)"
       
  2461   apply (unfold word_msb_nth uint_bl)
       
  2462   apply (subst hd_conv_nth)
       
  2463   apply (rule length_greater_0_conv [THEN iffD1])
       
  2464    apply simp
       
  2465   apply (simp add : nth_bin_to_bl word_size)
       
  2466   done
       
  2467 
       
  2468 lemma word_set_nth:
       
  2469   "set_bit w n (test_bit w n) = (w::'a::len0 word)"
       
  2470   unfolding word_test_bit_def word_set_bit_def by auto
       
  2471 
       
  2472 lemma bin_nth_uint':
       
  2473   "bin_nth (uint w) n = (rev (bin_to_bl (size w) (uint w)) ! n & n < size w)"
       
  2474   apply (unfold word_size)
       
  2475   apply (safe elim!: bin_nth_uint_imp)
       
  2476    apply (frule bin_nth_uint_imp)
       
  2477    apply (fast dest!: bin_nth_bl)+
       
  2478   done
       
  2479 
       
  2480 lemmas bin_nth_uint = bin_nth_uint' [unfolded word_size]
       
  2481 
       
  2482 lemma test_bit_bl: "w !! n = (rev (to_bl w) ! n & n < size w)"
       
  2483   unfolding to_bl_def word_test_bit_def word_size
       
  2484   by (rule bin_nth_uint)
       
  2485 
       
  2486 lemma to_bl_nth: "n < size w ==> to_bl w ! n = w !! (size w - Suc n)"
       
  2487   apply (unfold test_bit_bl)
       
  2488   apply clarsimp
       
  2489   apply (rule trans)
       
  2490    apply (rule nth_rev_alt)
       
  2491    apply (auto simp add: word_size)
       
  2492   done
       
  2493 
       
  2494 lemma test_bit_set: 
       
  2495   fixes w :: "'a::len0 word"
       
  2496   shows "(set_bit w n x) !! n = (n < size w & x)"
       
  2497   unfolding word_size word_test_bit_def word_set_bit_def
       
  2498   by (clarsimp simp add : word_ubin.eq_norm nth_bintr)
       
  2499 
       
  2500 lemma test_bit_set_gen: 
       
  2501   fixes w :: "'a::len0 word"
       
  2502   shows "test_bit (set_bit w n x) m = 
       
  2503          (if m = n then n < size w & x else test_bit w m)"
       
  2504   apply (unfold word_size word_test_bit_def word_set_bit_def)
       
  2505   apply (clarsimp simp add: word_ubin.eq_norm nth_bintr bin_nth_sc_gen)
       
  2506   apply (auto elim!: test_bit_size [unfolded word_size]
       
  2507               simp add: word_test_bit_def [symmetric])
       
  2508   done
       
  2509 
       
  2510 lemma of_bl_rep_False: "of_bl (replicate n False @ bs) = of_bl bs"
       
  2511   unfolding of_bl_def bl_to_bin_rep_F by auto
       
  2512   
       
  2513 lemma msb_nth':
       
  2514   fixes w :: "'a::len word"
       
  2515   shows "msb w = w !! (size w - 1)"
       
  2516   unfolding word_msb_nth' word_test_bit_def by simp
       
  2517 
       
  2518 lemmas msb_nth = msb_nth' [unfolded word_size]
       
  2519 
       
  2520 lemmas msb0 = len_gt_0 [THEN diff_Suc_less, THEN
       
  2521   word_ops_nth_size [unfolded word_size], standard]
       
  2522 lemmas msb1 = msb0 [where i = 0]
       
  2523 lemmas word_ops_msb = msb1 [unfolded msb_nth [symmetric, unfolded One_nat_def]]
       
  2524 
       
  2525 lemmas lsb0 = len_gt_0 [THEN word_ops_nth_size [unfolded word_size], standard]
       
  2526 lemmas word_ops_lsb = lsb0 [unfolded word_lsb_alt]
       
  2527 
       
  2528 lemma td_ext_nth':
       
  2529   "n = size (w::'a::len0 word) ==> ofn = set_bits ==> [w, ofn g] = l ==> 
       
  2530     td_ext test_bit ofn {f. ALL i. f i --> i < n} (%h i. h i & i < n)"
       
  2531   apply (unfold word_size td_ext_def')
       
  2532   apply (safe del: subset_antisym)
       
  2533      apply (rule_tac [3] ext)
       
  2534      apply (rule_tac [4] ext)
       
  2535      apply (unfold word_size of_nth_def test_bit_bl)
       
  2536      apply safe
       
  2537        defer
       
  2538        apply (clarsimp simp: word_bl.Abs_inverse)+
       
  2539   apply (rule word_bl.Rep_inverse')
       
  2540   apply (rule sym [THEN trans])
       
  2541   apply (rule bl_of_nth_nth)
       
  2542   apply simp
       
  2543   apply (rule bl_of_nth_inj)
       
  2544   apply (clarsimp simp add : test_bit_bl word_size)
       
  2545   done
       
  2546 
       
  2547 lemmas td_ext_nth = td_ext_nth' [OF refl refl refl, unfolded word_size]
       
  2548 
       
  2549 interpretation test_bit:
       
  2550   td_ext "op !! :: 'a::len0 word => nat => bool"
       
  2551          set_bits
       
  2552          "{f. \<forall>i. f i \<longrightarrow> i < len_of TYPE('a::len0)}"
       
  2553          "(\<lambda>h i. h i \<and> i < len_of TYPE('a::len0))"
       
  2554   by (rule td_ext_nth)
       
  2555 
       
  2556 declare test_bit.Rep' [simp del]
       
  2557 declare test_bit.Rep' [rule del]
       
  2558 
       
  2559 lemmas td_nth = test_bit.td_thm
       
  2560 
       
  2561 lemma word_set_set_same: 
       
  2562   fixes w :: "'a::len0 word"
       
  2563   shows "set_bit (set_bit w n x) n y = set_bit w n y" 
       
  2564   by (rule word_eqI) (simp add : test_bit_set_gen word_size)
       
  2565     
       
  2566 lemma word_set_set_diff: 
       
  2567   fixes w :: "'a::len0 word"
       
  2568   assumes "m ~= n"
       
  2569   shows "set_bit (set_bit w m x) n y = set_bit (set_bit w n y) m x" 
       
  2570   by (rule word_eqI) (clarsimp simp add : test_bit_set_gen word_size prems)
       
  2571     
       
  2572 lemma test_bit_no': 
       
  2573   fixes w :: "'a::len0 word"
       
  2574   shows "w = number_of bin ==> test_bit w n = (n < size w & bin_nth bin n)"
       
  2575   unfolding word_test_bit_def word_number_of_def word_size
       
  2576   by (simp add : nth_bintr [symmetric] word_ubin.eq_norm)
       
  2577 
       
  2578 lemmas test_bit_no = 
       
  2579   refl [THEN test_bit_no', unfolded word_size, THEN eq_reflection, standard]
       
  2580 
       
  2581 lemma nth_0: "~ (0::'a::len0 word) !! n"
       
  2582   unfolding test_bit_no word_0_no by auto
       
  2583 
       
  2584 lemma nth_sint: 
       
  2585   fixes w :: "'a::len word"
       
  2586   defines "l \<equiv> len_of TYPE ('a)"
       
  2587   shows "bin_nth (sint w) n = (if n < l - 1 then w !! n else w !! (l - 1))"
       
  2588   unfolding sint_uint l_def
       
  2589   by (clarsimp simp add: nth_sbintr word_test_bit_def [symmetric])
       
  2590 
       
  2591 lemma word_lsb_no: 
       
  2592   "lsb (number_of bin :: 'a :: len word) = (bin_last bin = 1)"
       
  2593   unfolding word_lsb_alt test_bit_no by auto
       
  2594 
       
  2595 lemma word_set_no: 
       
  2596   "set_bit (number_of bin::'a::len0 word) n b = 
       
  2597     number_of (bin_sc n (if b then 1 else 0) bin)"
       
  2598   apply (unfold word_set_bit_def word_number_of_def [symmetric])
       
  2599   apply (rule word_eqI)
       
  2600   apply (clarsimp simp: word_size bin_nth_sc_gen number_of_is_id 
       
  2601                         test_bit_no nth_bintr)
       
  2602   done
       
  2603 
       
  2604 lemmas setBit_no = setBit_def [THEN trans [OF meta_eq_to_obj_eq word_set_no],
       
  2605   simplified if_simps, THEN eq_reflection, standard]
       
  2606 lemmas clearBit_no = clearBit_def [THEN trans [OF meta_eq_to_obj_eq word_set_no],
       
  2607   simplified if_simps, THEN eq_reflection, standard]
       
  2608 
       
  2609 lemma to_bl_n1: 
       
  2610   "to_bl (-1::'a::len0 word) = replicate (len_of TYPE ('a)) True"
       
  2611   apply (rule word_bl.Abs_inverse')
       
  2612    apply simp
       
  2613   apply (rule word_eqI)
       
  2614   apply (clarsimp simp add: word_size test_bit_no)
       
  2615   apply (auto simp add: word_bl.Abs_inverse test_bit_bl word_size)
       
  2616   done
       
  2617 
       
  2618 lemma word_msb_n1: "msb (-1::'a::len word)"
       
  2619   unfolding word_msb_alt word_msb_alt to_bl_n1 by simp
       
  2620 
       
  2621 declare word_set_set_same [simp] word_set_nth [simp]
       
  2622   test_bit_no [simp] word_set_no [simp] nth_0 [simp]
       
  2623   setBit_no [simp] clearBit_no [simp]
       
  2624   word_lsb_no [simp] word_msb_no [simp] word_msb_n1 [simp] word_lsb_1_0 [simp]
       
  2625 
       
  2626 lemma word_set_nth_iff: 
       
  2627   "(set_bit w n b = w) = (w !! n = b | n >= size (w::'a::len0 word))"
       
  2628   apply (rule iffI)
       
  2629    apply (rule disjCI)
       
  2630    apply (drule word_eqD)
       
  2631    apply (erule sym [THEN trans])
       
  2632    apply (simp add: test_bit_set)
       
  2633   apply (erule disjE)
       
  2634    apply clarsimp
       
  2635   apply (rule word_eqI)
       
  2636   apply (clarsimp simp add : test_bit_set_gen)
       
  2637   apply (drule test_bit_size)
       
  2638   apply force
       
  2639   done
       
  2640 
       
  2641 lemma test_bit_2p': 
       
  2642   "w = word_of_int (2 ^ n) ==> 
       
  2643     w !! m = (m = n & m < size (w :: 'a :: len word))"
       
  2644   unfolding word_test_bit_def word_size
       
  2645   by (auto simp add: word_ubin.eq_norm nth_bintr nth_2p_bin)
       
  2646 
       
  2647 lemmas test_bit_2p = refl [THEN test_bit_2p', unfolded word_size]
       
  2648 
       
  2649 lemma nth_w2p:
       
  2650   "((2\<Colon>'a\<Colon>len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < len_of TYPE('a\<Colon>len)"
       
  2651   unfolding test_bit_2p [symmetric] word_of_int [symmetric]
       
  2652   by (simp add:  of_int_power)
       
  2653 
       
  2654 lemma uint_2p: 
       
  2655   "(0::'a::len word) < 2 ^ n ==> uint (2 ^ n::'a::len word) = 2 ^ n"
       
  2656   apply (unfold word_arith_power_alt)
       
  2657   apply (case_tac "len_of TYPE ('a)")
       
  2658    apply clarsimp
       
  2659   apply (case_tac "nat")
       
  2660    apply clarsimp
       
  2661    apply (case_tac "n")
       
  2662     apply (clarsimp simp add : word_1_wi [symmetric])
       
  2663    apply (clarsimp simp add : word_0_wi [symmetric])
       
  2664   apply (drule word_gt_0 [THEN iffD1])
       
  2665   apply (safe intro!: word_eqI bin_nth_lem ext)
       
  2666      apply (auto simp add: test_bit_2p nth_2p_bin word_test_bit_def [symmetric])
       
  2667   done
       
  2668 
       
  2669 lemma word_of_int_2p: "(word_of_int (2 ^ n) :: 'a :: len word) = 2 ^ n" 
       
  2670   apply (unfold word_arith_power_alt)
       
  2671   apply (case_tac "len_of TYPE ('a)")
       
  2672    apply clarsimp
       
  2673   apply (case_tac "nat")
       
  2674    apply (rule word_ubin.norm_eq_iff [THEN iffD1]) 
       
  2675    apply (rule box_equals) 
       
  2676      apply (rule_tac [2] bintr_ariths (1))+ 
       
  2677    apply (clarsimp simp add : number_of_is_id)
       
  2678   apply simp 
       
  2679   done
       
  2680 
       
  2681 lemma bang_is_le: "x !! m ==> 2 ^ m <= (x :: 'a :: len word)" 
       
  2682   apply (rule xtr3) 
       
  2683   apply (rule_tac [2] y = "x" in le_word_or2)
       
  2684   apply (rule word_eqI)
       
  2685   apply (auto simp add: word_ao_nth nth_w2p word_size)
       
  2686   done
       
  2687 
       
  2688 lemma word_clr_le: 
       
  2689   fixes w :: "'a::len0 word"
       
  2690   shows "w >= set_bit w n False"
       
  2691   apply (unfold word_set_bit_def word_le_def word_ubin.eq_norm)
       
  2692   apply simp
       
  2693   apply (rule order_trans)
       
  2694    apply (rule bintr_bin_clr_le)
       
  2695   apply simp
       
  2696   done
       
  2697 
       
  2698 lemma word_set_ge: 
       
  2699   fixes w :: "'a::len word"
       
  2700   shows "w <= set_bit w n True"
       
  2701   apply (unfold word_set_bit_def word_le_def word_ubin.eq_norm)
       
  2702   apply simp
       
  2703   apply (rule order_trans [OF _ bintr_bin_set_ge])
       
  2704   apply simp
       
  2705   done
       
  2706 
       
  2707 
       
  2708 subsection {* Shifting, Rotating, and Splitting Words *}
       
  2709 
       
  2710 lemma shiftl1_number [simp] :
       
  2711   "shiftl1 (number_of w) = number_of (w BIT 0)"
       
  2712   apply (unfold shiftl1_def word_number_of_def)
       
  2713   apply (simp add: word_ubin.norm_eq_iff [symmetric] word_ubin.eq_norm
       
  2714               del: BIT_simps)
       
  2715   apply (subst refl [THEN bintrunc_BIT_I, symmetric])
       
  2716   apply (subst bintrunc_bintrunc_min)
       
  2717   apply simp
       
  2718   done
       
  2719 
       
  2720 lemma shiftl1_0 [simp] : "shiftl1 0 = 0"
       
  2721   unfolding word_0_no shiftl1_number by auto
       
  2722 
       
  2723 lemmas shiftl1_def_u = shiftl1_def [folded word_number_of_def]
       
  2724 
       
  2725 lemma shiftl1_def_s: "shiftl1 w = number_of (sint w BIT 0)"
       
  2726   by (rule trans [OF _ shiftl1_number]) simp
       
  2727 
       
  2728 lemma shiftr1_0 [simp] : "shiftr1 0 = 0"
       
  2729   unfolding shiftr1_def 
       
  2730   by simp (simp add: word_0_wi)
       
  2731 
       
  2732 lemma sshiftr1_0 [simp] : "sshiftr1 0 = 0"
       
  2733   apply (unfold sshiftr1_def)
       
  2734   apply simp
       
  2735   apply (simp add : word_0_wi)
       
  2736   done
       
  2737 
       
  2738 lemma sshiftr1_n1 [simp] : "sshiftr1 -1 = -1"
       
  2739   unfolding sshiftr1_def by auto
       
  2740 
       
  2741 lemma shiftl_0 [simp] : "(0::'a::len0 word) << n = 0"
       
  2742   unfolding shiftl_def by (induct n) auto
       
  2743 
       
  2744 lemma shiftr_0 [simp] : "(0::'a::len0 word) >> n = 0"
       
  2745   unfolding shiftr_def by (induct n) auto
       
  2746 
       
  2747 lemma sshiftr_0 [simp] : "0 >>> n = 0"
       
  2748   unfolding sshiftr_def by (induct n) auto
       
  2749 
       
  2750 lemma sshiftr_n1 [simp] : "-1 >>> n = -1"
       
  2751   unfolding sshiftr_def by (induct n) auto
       
  2752 
       
  2753 lemma nth_shiftl1: "shiftl1 w !! n = (n < size w & n > 0 & w !! (n - 1))"
       
  2754   apply (unfold shiftl1_def word_test_bit_def)
       
  2755   apply (simp add: nth_bintr word_ubin.eq_norm word_size)
       
  2756   apply (cases n)
       
  2757    apply auto
       
  2758   done
       
  2759 
       
  2760 lemma nth_shiftl' [rule_format]:
       
  2761   "ALL n. ((w::'a::len0 word) << m) !! n = (n < size w & n >= m & w !! (n - m))"
       
  2762   apply (unfold shiftl_def)
       
  2763   apply (induct "m")
       
  2764    apply (force elim!: test_bit_size)
       
  2765   apply (clarsimp simp add : nth_shiftl1 word_size)
       
  2766   apply arith
       
  2767   done
       
  2768 
       
  2769 lemmas nth_shiftl = nth_shiftl' [unfolded word_size] 
       
  2770 
       
  2771 lemma nth_shiftr1: "shiftr1 w !! n = w !! Suc n"
       
  2772   apply (unfold shiftr1_def word_test_bit_def)
       
  2773   apply (simp add: nth_bintr word_ubin.eq_norm)
       
  2774   apply safe
       
  2775   apply (drule bin_nth.Suc [THEN iffD2, THEN bin_nth_uint_imp])
       
  2776   apply simp
       
  2777   done
       
  2778 
       
  2779 lemma nth_shiftr: 
       
  2780   "\<And>n. ((w::'a::len0 word) >> m) !! n = w !! (n + m)"
       
  2781   apply (unfold shiftr_def)
       
  2782   apply (induct "m")
       
  2783    apply (auto simp add : nth_shiftr1)
       
  2784   done
       
  2785    
       
  2786 (* see paper page 10, (1), (2), shiftr1_def is of the form of (1),
       
  2787   where f (ie bin_rest) takes normal arguments to normal results,
       
  2788   thus we get (2) from (1) *)
       
  2789 
       
  2790 lemma uint_shiftr1: "uint (shiftr1 w) = bin_rest (uint w)" 
       
  2791   apply (unfold shiftr1_def word_ubin.eq_norm bin_rest_trunc_i)
       
  2792   apply (subst bintr_uint [symmetric, OF order_refl])
       
  2793   apply (simp only : bintrunc_bintrunc_l)
       
  2794   apply simp 
       
  2795   done
       
  2796 
       
  2797 lemma nth_sshiftr1: 
       
  2798   "sshiftr1 w !! n = (if n = size w - 1 then w !! n else w !! Suc n)"
       
  2799   apply (unfold sshiftr1_def word_test_bit_def)
       
  2800   apply (simp add: nth_bintr word_ubin.eq_norm
       
  2801                    bin_nth.Suc [symmetric] word_size 
       
  2802              del: bin_nth.simps)
       
  2803   apply (simp add: nth_bintr uint_sint del : bin_nth.simps)
       
  2804   apply (auto simp add: bin_nth_sint)
       
  2805   done
       
  2806 
       
  2807 lemma nth_sshiftr [rule_format] : 
       
  2808   "ALL n. sshiftr w m !! n = (n < size w & 
       
  2809     (if n + m >= size w then w !! (size w - 1) else w !! (n + m)))"
       
  2810   apply (unfold sshiftr_def)
       
  2811   apply (induct_tac "m")
       
  2812    apply (simp add: test_bit_bl)
       
  2813   apply (clarsimp simp add: nth_sshiftr1 word_size)
       
  2814   apply safe
       
  2815        apply arith
       
  2816       apply arith
       
  2817      apply (erule thin_rl)
       
  2818      apply (case_tac n)
       
  2819       apply safe
       
  2820       apply simp
       
  2821      apply simp
       
  2822     apply (erule thin_rl)
       
  2823     apply (case_tac n)
       
  2824      apply safe
       
  2825      apply simp
       
  2826     apply simp
       
  2827    apply arith+
       
  2828   done
       
  2829     
       
  2830 lemma shiftr1_div_2: "uint (shiftr1 w) = uint w div 2"
       
  2831   apply (unfold shiftr1_def bin_rest_div)
       
  2832   apply (rule word_uint.Abs_inverse)
       
  2833   apply (simp add: uints_num pos_imp_zdiv_nonneg_iff)
       
  2834   apply (rule xtr7)
       
  2835    prefer 2
       
  2836    apply (rule zdiv_le_dividend)
       
  2837     apply auto
       
  2838   done
       
  2839 
       
  2840 lemma sshiftr1_div_2: "sint (sshiftr1 w) = sint w div 2"
       
  2841   apply (unfold sshiftr1_def bin_rest_div [symmetric])
       
  2842   apply (simp add: word_sbin.eq_norm)
       
  2843   apply (rule trans)
       
  2844    defer
       
  2845    apply (subst word_sbin.norm_Rep [symmetric])
       
  2846    apply (rule refl)
       
  2847   apply (subst word_sbin.norm_Rep [symmetric])
       
  2848   apply (unfold One_nat_def)
       
  2849   apply (rule sbintrunc_rest)
       
  2850   done
       
  2851 
       
  2852 lemma shiftr_div_2n: "uint (shiftr w n) = uint w div 2 ^ n"
       
  2853   apply (unfold shiftr_def)
       
  2854   apply (induct "n")
       
  2855    apply simp
       
  2856   apply (simp add: shiftr1_div_2 mult_commute
       
  2857                    zdiv_zmult2_eq [symmetric])
       
  2858   done
       
  2859 
       
  2860 lemma sshiftr_div_2n: "sint (sshiftr w n) = sint w div 2 ^ n"
       
  2861   apply (unfold sshiftr_def)
       
  2862   apply (induct "n")
       
  2863    apply simp
       
  2864   apply (simp add: sshiftr1_div_2 mult_commute
       
  2865                    zdiv_zmult2_eq [symmetric])
       
  2866   done
       
  2867 
       
  2868 subsubsection "shift functions in terms of lists of bools"
       
  2869 
       
  2870 lemmas bshiftr1_no_bin [simp] = 
       
  2871   bshiftr1_def [where w="number_of w", unfolded to_bl_no_bin, standard]
       
  2872 
       
  2873 lemma bshiftr1_bl: "to_bl (bshiftr1 b w) = b # butlast (to_bl w)"
       
  2874   unfolding bshiftr1_def by (rule word_bl.Abs_inverse) simp
       
  2875 
       
  2876 lemma shiftl1_of_bl: "shiftl1 (of_bl bl) = of_bl (bl @ [False])"
       
  2877   unfolding uint_bl of_bl_no 
       
  2878   by (simp add: bl_to_bin_aux_append bl_to_bin_def)
       
  2879 
       
  2880 lemma shiftl1_bl: "shiftl1 (w::'a::len0 word) = of_bl (to_bl w @ [False])"
       
  2881 proof -
       
  2882   have "shiftl1 w = shiftl1 (of_bl (to_bl w))" by simp
       
  2883   also have "\<dots> = of_bl (to_bl w @ [False])" by (rule shiftl1_of_bl)
       
  2884   finally show ?thesis .
       
  2885 qed
       
  2886 
       
  2887 lemma bl_shiftl1:
       
  2888   "to_bl (shiftl1 (w :: 'a :: len word)) = tl (to_bl w) @ [False]"
       
  2889   apply (simp add: shiftl1_bl word_rep_drop drop_Suc drop_Cons')
       
  2890   apply (fast intro!: Suc_leI)
       
  2891   done
       
  2892 
       
  2893 lemma shiftr1_bl: "shiftr1 w = of_bl (butlast (to_bl w))"
       
  2894   apply (unfold shiftr1_def uint_bl of_bl_def)
       
  2895   apply (simp add: butlast_rest_bin word_size)
       
  2896   apply (simp add: bin_rest_trunc [symmetric, unfolded One_nat_def])
       
  2897   done
       
  2898 
       
  2899 lemma bl_shiftr1: 
       
  2900   "to_bl (shiftr1 (w :: 'a :: len word)) = False # butlast (to_bl w)"
       
  2901   unfolding shiftr1_bl
       
  2902   by (simp add : word_rep_drop len_gt_0 [THEN Suc_leI])
       
  2903 
       
  2904 
       
  2905 (* relate the two above : TODO - remove the :: len restriction on
       
  2906   this theorem and others depending on it *)
       
  2907 lemma shiftl1_rev: 
       
  2908   "shiftl1 (w :: 'a :: len word) = word_reverse (shiftr1 (word_reverse w))"
       
  2909   apply (unfold word_reverse_def)
       
  2910   apply (rule word_bl.Rep_inverse' [symmetric])
       
  2911   apply (simp add: bl_shiftl1 bl_shiftr1 word_bl.Abs_inverse)
       
  2912   apply (cases "to_bl w")
       
  2913    apply auto
       
  2914   done
       
  2915 
       
  2916 lemma shiftl_rev: 
       
  2917   "shiftl (w :: 'a :: len word) n = word_reverse (shiftr (word_reverse w) n)"
       
  2918   apply (unfold shiftl_def shiftr_def)
       
  2919   apply (induct "n")
       
  2920    apply (auto simp add : shiftl1_rev)
       
  2921   done
       
  2922 
       
  2923 lemmas rev_shiftl =
       
  2924   shiftl_rev [where w = "word_reverse w", simplified, standard]
       
  2925 
       
  2926 lemmas shiftr_rev = rev_shiftl [THEN word_rev_gal', standard]
       
  2927 lemmas rev_shiftr = shiftl_rev [THEN word_rev_gal', standard]
       
  2928 
       
  2929 lemma bl_sshiftr1:
       
  2930   "to_bl (sshiftr1 (w :: 'a :: len word)) = hd (to_bl w) # butlast (to_bl w)"
       
  2931   apply (unfold sshiftr1_def uint_bl word_size)
       
  2932   apply (simp add: butlast_rest_bin word_ubin.eq_norm)
       
  2933   apply (simp add: sint_uint)
       
  2934   apply (rule nth_equalityI)
       
  2935    apply clarsimp
       
  2936   apply clarsimp
       
  2937   apply (case_tac i)
       
  2938    apply (simp_all add: hd_conv_nth length_0_conv [symmetric]
       
  2939                         nth_bin_to_bl bin_nth.Suc [symmetric] 
       
  2940                         nth_sbintr 
       
  2941                    del: bin_nth.Suc)
       
  2942    apply force
       
  2943   apply (rule impI)
       
  2944   apply (rule_tac f = "bin_nth (uint w)" in arg_cong)
       
  2945   apply simp
       
  2946   done
       
  2947 
       
  2948 lemma drop_shiftr: 
       
  2949   "drop n (to_bl ((w :: 'a :: len word) >> n)) = take (size w - n) (to_bl w)" 
       
  2950   apply (unfold shiftr_def)
       
  2951   apply (induct n)
       
  2952    prefer 2
       
  2953    apply (simp add: drop_Suc bl_shiftr1 butlast_drop [symmetric])
       
  2954    apply (rule butlast_take [THEN trans])
       
  2955   apply (auto simp: word_size)
       
  2956   done
       
  2957 
       
  2958 lemma drop_sshiftr: 
       
  2959   "drop n (to_bl ((w :: 'a :: len word) >>> n)) = take (size w - n) (to_bl w)"
       
  2960   apply (unfold sshiftr_def)
       
  2961   apply (induct n)
       
  2962    prefer 2
       
  2963    apply (simp add: drop_Suc bl_sshiftr1 butlast_drop [symmetric])
       
  2964    apply (rule butlast_take [THEN trans])
       
  2965   apply (auto simp: word_size)
       
  2966   done
       
  2967 
       
  2968 lemma take_shiftr [rule_format] :
       
  2969   "n <= size (w :: 'a :: len word) --> take n (to_bl (w >> n)) = 
       
  2970     replicate n False" 
       
  2971   apply (unfold shiftr_def)
       
  2972   apply (induct n)
       
  2973    prefer 2
       
  2974    apply (simp add: bl_shiftr1)
       
  2975    apply (rule impI)
       
  2976    apply (rule take_butlast [THEN trans])
       
  2977   apply (auto simp: word_size)
       
  2978   done
       
  2979 
       
  2980 lemma take_sshiftr' [rule_format] :
       
  2981   "n <= size (w :: 'a :: len word) --> hd (to_bl (w >>> n)) = hd (to_bl w) & 
       
  2982     take n (to_bl (w >>> n)) = replicate n (hd (to_bl w))" 
       
  2983   apply (unfold sshiftr_def)
       
  2984   apply (induct n)
       
  2985    prefer 2
       
  2986    apply (simp add: bl_sshiftr1)
       
  2987    apply (rule impI)
       
  2988    apply (rule take_butlast [THEN trans])
       
  2989   apply (auto simp: word_size)
       
  2990   done
       
  2991 
       
  2992 lemmas hd_sshiftr = take_sshiftr' [THEN conjunct1, standard]
       
  2993 lemmas take_sshiftr = take_sshiftr' [THEN conjunct2, standard]
       
  2994 
       
  2995 lemma atd_lem: "take n xs = t ==> drop n xs = d ==> xs = t @ d"
       
  2996   by (auto intro: append_take_drop_id [symmetric])
       
  2997 
       
  2998 lemmas bl_shiftr = atd_lem [OF take_shiftr drop_shiftr]
       
  2999 lemmas bl_sshiftr = atd_lem [OF take_sshiftr drop_sshiftr]
       
  3000 
       
  3001 lemma shiftl_of_bl: "of_bl bl << n = of_bl (bl @ replicate n False)"
       
  3002   unfolding shiftl_def
       
  3003   by (induct n) (auto simp: shiftl1_of_bl replicate_app_Cons_same)
       
  3004 
       
  3005 lemma shiftl_bl:
       
  3006   "(w::'a::len0 word) << (n::nat) = of_bl (to_bl w @ replicate n False)"
       
  3007 proof -
       
  3008   have "w << n = of_bl (to_bl w) << n" by simp
       
  3009   also have "\<dots> = of_bl (to_bl w @ replicate n False)" by (rule shiftl_of_bl)
       
  3010   finally show ?thesis .
       
  3011 qed
       
  3012 
       
  3013 lemmas shiftl_number [simp] = shiftl_def [where w="number_of w", standard]
       
  3014 
       
  3015 lemma bl_shiftl:
       
  3016   "to_bl (w << n) = drop n (to_bl w) @ replicate (min (size w) n) False"
       
  3017   by (simp add: shiftl_bl word_rep_drop word_size)
       
  3018 
       
  3019 lemma shiftl_zero_size: 
       
  3020   fixes x :: "'a::len0 word"
       
  3021   shows "size x <= n ==> x << n = 0"
       
  3022   apply (unfold word_size)
       
  3023   apply (rule word_eqI)
       
  3024   apply (clarsimp simp add: shiftl_bl word_size test_bit_of_bl nth_append)
       
  3025   done
       
  3026 
       
  3027 (* note - the following results use 'a :: len word < number_ring *)
       
  3028 
       
  3029 lemma shiftl1_2t: "shiftl1 (w :: 'a :: len word) = 2 * w"
       
  3030   apply (simp add: shiftl1_def_u)
       
  3031   apply (simp only:  double_number_of_Bit0 [symmetric])
       
  3032   apply simp
       
  3033   done
       
  3034 
       
  3035 lemma shiftl1_p: "shiftl1 (w :: 'a :: len word) = w + w"
       
  3036   apply (simp add: shiftl1_def_u)
       
  3037   apply (simp only: double_number_of_Bit0 [symmetric])
       
  3038   apply simp
       
  3039   done
       
  3040 
       
  3041 lemma shiftl_t2n: "shiftl (w :: 'a :: len word) n = 2 ^ n * w"
       
  3042   unfolding shiftl_def 
       
  3043   by (induct n) (auto simp: shiftl1_2t power_Suc)
       
  3044 
       
  3045 lemma shiftr1_bintr [simp]:
       
  3046   "(shiftr1 (number_of w) :: 'a :: len0 word) = 
       
  3047     number_of (bin_rest (bintrunc (len_of TYPE ('a)) w))" 
       
  3048   unfolding shiftr1_def word_number_of_def
       
  3049   by (simp add : word_ubin.eq_norm)
       
  3050 
       
  3051 lemma sshiftr1_sbintr [simp] :
       
  3052   "(sshiftr1 (number_of w) :: 'a :: len word) = 
       
  3053     number_of (bin_rest (sbintrunc (len_of TYPE ('a) - 1) w))" 
       
  3054   unfolding sshiftr1_def word_number_of_def
       
  3055   by (simp add : word_sbin.eq_norm)
       
  3056 
       
  3057 lemma shiftr_no': 
       
  3058   "w = number_of bin ==> 
       
  3059   (w::'a::len0 word) >> n = number_of ((bin_rest ^^ n) (bintrunc (size w) bin))"
       
  3060   apply clarsimp
       
  3061   apply (rule word_eqI)
       
  3062   apply (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size)
       
  3063   done
       
  3064 
       
  3065 lemma sshiftr_no': 
       
  3066   "w = number_of bin ==> w >>> n = number_of ((bin_rest ^^ n) 
       
  3067     (sbintrunc (size w - 1) bin))"
       
  3068   apply clarsimp
       
  3069   apply (rule word_eqI)
       
  3070   apply (auto simp: nth_sshiftr nth_rest_power_bin nth_sbintr word_size)
       
  3071    apply (subgoal_tac "na + n = len_of TYPE('a) - Suc 0", simp, simp)+
       
  3072   done
       
  3073 
       
  3074 lemmas sshiftr_no [simp] = 
       
  3075   sshiftr_no' [where w = "number_of w", OF refl, unfolded word_size, standard]
       
  3076 
       
  3077 lemmas shiftr_no [simp] = 
       
  3078   shiftr_no' [where w = "number_of w", OF refl, unfolded word_size, standard]
       
  3079 
       
  3080 lemma shiftr1_bl_of': 
       
  3081   "us = shiftr1 (of_bl bl) ==> length bl <= size us ==> 
       
  3082     us = of_bl (butlast bl)"
       
  3083   by (clarsimp simp: shiftr1_def of_bl_def word_size butlast_rest_bl2bin 
       
  3084                      word_ubin.eq_norm trunc_bl2bin)
       
  3085 
       
  3086 lemmas shiftr1_bl_of = refl [THEN shiftr1_bl_of', unfolded word_size]
       
  3087 
       
  3088 lemma shiftr_bl_of' [rule_format]: 
       
  3089   "us = of_bl bl >> n ==> length bl <= size us --> 
       
  3090    us = of_bl (take (length bl - n) bl)"
       
  3091   apply (unfold shiftr_def)
       
  3092   apply hypsubst
       
  3093   apply (unfold word_size)
       
  3094   apply (induct n)
       
  3095    apply clarsimp
       
  3096   apply clarsimp
       
  3097   apply (subst shiftr1_bl_of)
       
  3098    apply simp
       
  3099   apply (simp add: butlast_take)
       
  3100   done
       
  3101 
       
  3102 lemmas shiftr_bl_of = refl [THEN shiftr_bl_of', unfolded word_size]
       
  3103 
       
  3104 lemmas shiftr_bl = word_bl.Rep' [THEN eq_imp_le, THEN shiftr_bl_of,
       
  3105   simplified word_size, simplified, THEN eq_reflection, standard]
       
  3106 
       
  3107 lemma msb_shift': "msb (w::'a::len word) <-> (w >> (size w - 1)) ~= 0"
       
  3108   apply (unfold shiftr_bl word_msb_alt)
       
  3109   apply (simp add: word_size Suc_le_eq take_Suc)
       
  3110   apply (cases "hd (to_bl w)")
       
  3111    apply (auto simp: word_1_bl word_0_bl 
       
  3112                      of_bl_rep_False [where n=1 and bs="[]", simplified])
       
  3113   done
       
  3114 
       
  3115 lemmas msb_shift = msb_shift' [unfolded word_size]
       
  3116 
       
  3117 lemma align_lem_or [rule_format] :
       
  3118   "ALL x m. length x = n + m --> length y = n + m --> 
       
  3119     drop m x = replicate n False --> take m y = replicate m False --> 
       
  3120     map2 op | x y = take m x @ drop m y"
       
  3121   apply (induct_tac y)
       
  3122    apply force
       
  3123   apply clarsimp
       
  3124   apply (case_tac x, force)
       
  3125   apply (case_tac m, auto)
       
  3126   apply (drule sym)
       
  3127   apply auto
       
  3128   apply (induct_tac list, auto)
       
  3129   done
       
  3130 
       
  3131 lemma align_lem_and [rule_format] :
       
  3132   "ALL x m. length x = n + m --> length y = n + m --> 
       
  3133     drop m x = replicate n False --> take m y = replicate m False --> 
       
  3134     map2 op & x y = replicate (n + m) False"
       
  3135   apply (induct_tac y)
       
  3136    apply force
       
  3137   apply clarsimp
       
  3138   apply (case_tac x, force)
       
  3139   apply (case_tac m, auto)
       
  3140   apply (drule sym)
       
  3141   apply auto
       
  3142   apply (induct_tac list, auto)
       
  3143   done
       
  3144 
       
  3145 lemma aligned_bl_add_size':
       
  3146   "size x - n = m ==> n <= size x ==> drop m (to_bl x) = replicate n False ==>
       
  3147     take m (to_bl y) = replicate m False ==> 
       
  3148     to_bl (x + y) = take m (to_bl x) @ drop m (to_bl y)"
       
  3149   apply (subgoal_tac "x AND y = 0")
       
  3150    prefer 2
       
  3151    apply (rule word_bl.Rep_eqD)
       
  3152    apply (simp add: bl_word_and to_bl_0)
       
  3153    apply (rule align_lem_and [THEN trans])
       
  3154        apply (simp_all add: word_size)[5]
       
  3155    apply simp
       
  3156   apply (subst word_plus_and_or [symmetric])
       
  3157   apply (simp add : bl_word_or)
       
  3158   apply (rule align_lem_or)
       
  3159      apply (simp_all add: word_size)
       
  3160   done
       
  3161 
       
  3162 lemmas aligned_bl_add_size = refl [THEN aligned_bl_add_size']
       
  3163 
       
  3164 subsubsection "Mask"
       
  3165 
       
  3166 lemma nth_mask': "m = mask n ==> test_bit m i = (i < n & i < size m)"
       
  3167   apply (unfold mask_def test_bit_bl)
       
  3168   apply (simp only: word_1_bl [symmetric] shiftl_of_bl)
       
  3169   apply (clarsimp simp add: word_size)
       
  3170   apply (simp only: of_bl_no mask_lem number_of_succ add_diff_cancel2)
       
  3171   apply (fold of_bl_no)
       
  3172   apply (simp add: word_1_bl)
       
  3173   apply (rule test_bit_of_bl [THEN trans, unfolded test_bit_bl word_size])
       
  3174   apply auto
       
  3175   done
       
  3176 
       
  3177 lemmas nth_mask [simp] = refl [THEN nth_mask']
       
  3178 
       
  3179 lemma mask_bl: "mask n = of_bl (replicate n True)"
       
  3180   by (auto simp add : test_bit_of_bl word_size intro: word_eqI)
       
  3181 
       
  3182 lemma mask_bin: "mask n = number_of (bintrunc n Int.Min)"
       
  3183   by (auto simp add: nth_bintr word_size intro: word_eqI)
       
  3184 
       
  3185 lemma and_mask_bintr: "w AND mask n = number_of (bintrunc n (uint w))"
       
  3186   apply (rule word_eqI)
       
  3187   apply (simp add: nth_bintr word_size word_ops_nth_size)
       
  3188   apply (auto simp add: test_bit_bin)
       
  3189   done
       
  3190 
       
  3191 lemma and_mask_no: "number_of i AND mask n = number_of (bintrunc n i)" 
       
  3192   by (auto simp add : nth_bintr word_size word_ops_nth_size intro: word_eqI)
       
  3193 
       
  3194 lemmas and_mask_wi = and_mask_no [unfolded word_number_of_def] 
       
  3195 
       
  3196 lemma bl_and_mask':
       
  3197   "to_bl (w AND mask n :: 'a :: len word) = 
       
  3198     replicate (len_of TYPE('a) - n) False @ 
       
  3199     drop (len_of TYPE('a) - n) (to_bl w)"
       
  3200   apply (rule nth_equalityI)
       
  3201    apply simp
       
  3202   apply (clarsimp simp add: to_bl_nth word_size)
       
  3203   apply (simp add: word_size word_ops_nth_size)
       
  3204   apply (auto simp add: word_size test_bit_bl nth_append nth_rev)
       
  3205   done
       
  3206 
       
  3207 lemmas and_mask_mod_2p = 
       
  3208   and_mask_bintr [unfolded word_number_of_alt no_bintr_alt]
       
  3209 
       
  3210 lemma and_mask_lt_2p: "uint (w AND mask n) < 2 ^ n"
       
  3211   apply (simp add : and_mask_bintr no_bintr_alt)
       
  3212   apply (rule xtr8)
       
  3213    prefer 2
       
  3214    apply (rule pos_mod_bound)
       
  3215   apply auto
       
  3216   done
       
  3217 
       
  3218 lemmas eq_mod_iff = trans [symmetric, OF int_mod_lem eq_sym_conv]
       
  3219 
       
  3220 lemma mask_eq_iff: "(w AND mask n) = w <-> uint w < 2 ^ n"
       
  3221   apply (simp add: and_mask_bintr word_number_of_def)
       
  3222   apply (simp add: word_ubin.inverse_norm)
       
  3223   apply (simp add: eq_mod_iff bintrunc_mod2p min_def)
       
  3224   apply (fast intro!: lt2p_lem)
       
  3225   done
       
  3226 
       
  3227 lemma and_mask_dvd: "2 ^ n dvd uint w = (w AND mask n = 0)"
       
  3228   apply (simp add: dvd_eq_mod_eq_0 and_mask_mod_2p)
       
  3229   apply (simp add: word_uint.norm_eq_iff [symmetric] word_of_int_homs)
       
  3230   apply (subst word_uint.norm_Rep [symmetric])
       
  3231   apply (simp only: bintrunc_bintrunc_min bintrunc_mod2p [symmetric] min_def)
       
  3232   apply auto
       
  3233   done
       
  3234 
       
  3235 lemma and_mask_dvd_nat: "2 ^ n dvd unat w = (w AND mask n = 0)"
       
  3236   apply (unfold unat_def)
       
  3237   apply (rule trans [OF _ and_mask_dvd])
       
  3238   apply (unfold dvd_def) 
       
  3239   apply auto 
       
  3240   apply (drule uint_ge_0 [THEN nat_int.Abs_inverse' [simplified], symmetric])
       
  3241   apply (simp add : int_mult int_power)
       
  3242   apply (simp add : nat_mult_distrib nat_power_eq)
       
  3243   done
       
  3244 
       
  3245 lemma word_2p_lem: 
       
  3246   "n < size w ==> w < 2 ^ n = (uint (w :: 'a :: len word) < 2 ^ n)"
       
  3247   apply (unfold word_size word_less_alt word_number_of_alt)
       
  3248   apply (clarsimp simp add: word_of_int_power_hom word_uint.eq_norm 
       
  3249                             int_mod_eq'
       
  3250                   simp del: word_of_int_bin)
       
  3251   done
       
  3252 
       
  3253 lemma less_mask_eq: "x < 2 ^ n ==> x AND mask n = (x :: 'a :: len word)"
       
  3254   apply (unfold word_less_alt word_number_of_alt)
       
  3255   apply (clarsimp simp add: and_mask_mod_2p word_of_int_power_hom 
       
  3256                             word_uint.eq_norm
       
  3257                   simp del: word_of_int_bin)
       
  3258   apply (drule xtr8 [rotated])
       
  3259   apply (rule int_mod_le)
       
  3260   apply (auto simp add : mod_pos_pos_trivial)
       
  3261   done
       
  3262 
       
  3263 lemmas mask_eq_iff_w2p =
       
  3264   trans [OF mask_eq_iff word_2p_lem [symmetric], standard]
       
  3265 
       
  3266 lemmas and_mask_less' = 
       
  3267   iffD2 [OF word_2p_lem and_mask_lt_2p, simplified word_size, standard]
       
  3268 
       
  3269 lemma and_mask_less_size: "n < size x ==> x AND mask n < 2^n"
       
  3270   unfolding word_size by (erule and_mask_less')
       
  3271 
       
  3272 lemma word_mod_2p_is_mask':
       
  3273   "c = 2 ^ n ==> c > 0 ==> x mod c = (x :: 'a :: len word) AND mask n" 
       
  3274   by (clarsimp simp add: word_mod_def uint_2p and_mask_mod_2p) 
       
  3275 
       
  3276 lemmas word_mod_2p_is_mask = refl [THEN word_mod_2p_is_mask'] 
       
  3277 
       
  3278 lemma mask_eqs:
       
  3279   "(a AND mask n) + b AND mask n = a + b AND mask n"
       
  3280   "a + (b AND mask n) AND mask n = a + b AND mask n"
       
  3281   "(a AND mask n) - b AND mask n = a - b AND mask n"
       
  3282   "a - (b AND mask n) AND mask n = a - b AND mask n"
       
  3283   "a * (b AND mask n) AND mask n = a * b AND mask n"
       
  3284   "(b AND mask n) * a AND mask n = b * a AND mask n"
       
  3285   "(a AND mask n) + (b AND mask n) AND mask n = a + b AND mask n"
       
  3286   "(a AND mask n) - (b AND mask n) AND mask n = a - b AND mask n"
       
  3287   "(a AND mask n) * (b AND mask n) AND mask n = a * b AND mask n"
       
  3288   "- (a AND mask n) AND mask n = - a AND mask n"
       
  3289   "word_succ (a AND mask n) AND mask n = word_succ a AND mask n"
       
  3290   "word_pred (a AND mask n) AND mask n = word_pred a AND mask n"
       
  3291   using word_of_int_Ex [where x=a] word_of_int_Ex [where x=b]
       
  3292   by (auto simp: and_mask_wi bintr_ariths bintr_arith1s new_word_of_int_homs)
       
  3293 
       
  3294 lemma mask_power_eq:
       
  3295   "(x AND mask n) ^ k AND mask n = x ^ k AND mask n"
       
  3296   using word_of_int_Ex [where x=x]
       
  3297   by (clarsimp simp: and_mask_wi word_of_int_power_hom bintr_ariths)
       
  3298 
       
  3299 
       
  3300 subsubsection "Revcast"
       
  3301 
       
  3302 lemmas revcast_def' = revcast_def [simplified]
       
  3303 lemmas revcast_def'' = revcast_def' [simplified word_size]
       
  3304 lemmas revcast_no_def [simp] =
       
  3305   revcast_def' [where w="number_of w", unfolded word_size, standard]
       
  3306 
       
  3307 lemma to_bl_revcast: 
       
  3308   "to_bl (revcast w :: 'a :: len0 word) = 
       
  3309    takefill False (len_of TYPE ('a)) (to_bl w)"
       
  3310   apply (unfold revcast_def' word_size)
       
  3311   apply (rule word_bl.Abs_inverse)
       
  3312   apply simp
       
  3313   done
       
  3314 
       
  3315 lemma revcast_rev_ucast': 
       
  3316   "cs = [rc, uc] ==> rc = revcast (word_reverse w) ==> uc = ucast w ==> 
       
  3317     rc = word_reverse uc"
       
  3318   apply (unfold ucast_def revcast_def' Let_def word_reverse_def)
       
  3319   apply (clarsimp simp add : to_bl_of_bin takefill_bintrunc)
       
  3320   apply (simp add : word_bl.Abs_inverse word_size)
       
  3321   done
       
  3322 
       
  3323 lemmas revcast_rev_ucast = revcast_rev_ucast' [OF refl refl refl]
       
  3324 
       
  3325 lemmas revcast_ucast = revcast_rev_ucast
       
  3326   [where w = "word_reverse w", simplified word_rev_rev, standard]
       
  3327 
       
  3328 lemmas ucast_revcast = revcast_rev_ucast [THEN word_rev_gal', standard]
       
  3329 lemmas ucast_rev_revcast = revcast_ucast [THEN word_rev_gal', standard]
       
  3330 
       
  3331 
       
  3332 -- "linking revcast and cast via shift"
       
  3333 
       
  3334 lemmas wsst_TYs = source_size target_size word_size
       
  3335 
       
  3336 lemma revcast_down_uu': 
       
  3337   "rc = revcast ==> source_size rc = target_size rc + n ==> 
       
  3338     rc (w :: 'a :: len word) = ucast (w >> n)"
       
  3339   apply (simp add: revcast_def')
       
  3340   apply (rule word_bl.Rep_inverse')
       
  3341   apply (rule trans, rule ucast_down_drop)
       
  3342    prefer 2
       
  3343    apply (rule trans, rule drop_shiftr)
       
  3344    apply (auto simp: takefill_alt wsst_TYs)
       
  3345   done
       
  3346 
       
  3347 lemma revcast_down_us': 
       
  3348   "rc = revcast ==> source_size rc = target_size rc + n ==> 
       
  3349     rc (w :: 'a :: len word) = ucast (w >>> n)"
       
  3350   apply (simp add: revcast_def')
       
  3351   apply (rule word_bl.Rep_inverse')
       
  3352   apply (rule trans, rule ucast_down_drop)
       
  3353    prefer 2
       
  3354    apply (rule trans, rule drop_sshiftr)
       
  3355    apply (auto simp: takefill_alt wsst_TYs)
       
  3356   done
       
  3357 
       
  3358 lemma revcast_down_su': 
       
  3359   "rc = revcast ==> source_size rc = target_size rc + n ==> 
       
  3360     rc (w :: 'a :: len word) = scast (w >> n)"
       
  3361   apply (simp add: revcast_def')
       
  3362   apply (rule word_bl.Rep_inverse')
       
  3363   apply (rule trans, rule scast_down_drop)
       
  3364    prefer 2
       
  3365    apply (rule trans, rule drop_shiftr)
       
  3366    apply (auto simp: takefill_alt wsst_TYs)
       
  3367   done
       
  3368 
       
  3369 lemma revcast_down_ss': 
       
  3370   "rc = revcast ==> source_size rc = target_size rc + n ==> 
       
  3371     rc (w :: 'a :: len word) = scast (w >>> n)"
       
  3372   apply (simp add: revcast_def')
       
  3373   apply (rule word_bl.Rep_inverse')
       
  3374   apply (rule trans, rule scast_down_drop)
       
  3375    prefer 2
       
  3376    apply (rule trans, rule drop_sshiftr)
       
  3377    apply (auto simp: takefill_alt wsst_TYs)
       
  3378   done
       
  3379 
       
  3380 lemmas revcast_down_uu = refl [THEN revcast_down_uu']
       
  3381 lemmas revcast_down_us = refl [THEN revcast_down_us']
       
  3382 lemmas revcast_down_su = refl [THEN revcast_down_su']
       
  3383 lemmas revcast_down_ss = refl [THEN revcast_down_ss']
       
  3384 
       
  3385 lemma cast_down_rev: 
       
  3386   "uc = ucast ==> source_size uc = target_size uc + n ==> 
       
  3387     uc w = revcast ((w :: 'a :: len word) << n)"
       
  3388   apply (unfold shiftl_rev)
       
  3389   apply clarify
       
  3390   apply (simp add: revcast_rev_ucast)
       
  3391   apply (rule word_rev_gal')
       
  3392   apply (rule trans [OF _ revcast_rev_ucast])
       
  3393   apply (rule revcast_down_uu [symmetric])
       
  3394   apply (auto simp add: wsst_TYs)
       
  3395   done
       
  3396 
       
  3397 lemma revcast_up': 
       
  3398   "rc = revcast ==> source_size rc + n = target_size rc ==> 
       
  3399     rc w = (ucast w :: 'a :: len word) << n" 
       
  3400   apply (simp add: revcast_def')
       
  3401   apply (rule word_bl.Rep_inverse')
       
  3402   apply (simp add: takefill_alt)
       
  3403   apply (rule bl_shiftl [THEN trans])
       
  3404   apply (subst ucast_up_app)
       
  3405   apply (auto simp add: wsst_TYs)
       
  3406   done
       
  3407 
       
  3408 lemmas revcast_up = refl [THEN revcast_up']
       
  3409 
       
  3410 lemmas rc1 = revcast_up [THEN 
       
  3411   revcast_rev_ucast [symmetric, THEN trans, THEN word_rev_gal, symmetric]]
       
  3412 lemmas rc2 = revcast_down_uu [THEN 
       
  3413   revcast_rev_ucast [symmetric, THEN trans, THEN word_rev_gal, symmetric]]
       
  3414 
       
  3415 lemmas ucast_up =
       
  3416  rc1 [simplified rev_shiftr [symmetric] revcast_ucast [symmetric]]
       
  3417 lemmas ucast_down = 
       
  3418   rc2 [simplified rev_shiftr revcast_ucast [symmetric]]
       
  3419 
       
  3420 
       
  3421 subsubsection "Slices"
       
  3422 
       
  3423 lemmas slice1_no_bin [simp] =
       
  3424   slice1_def [where w="number_of w", unfolded to_bl_no_bin, standard]
       
  3425 
       
  3426 lemmas slice_no_bin [simp] = 
       
  3427    trans [OF slice_def [THEN meta_eq_to_obj_eq] 
       
  3428              slice1_no_bin [THEN meta_eq_to_obj_eq], 
       
  3429           unfolded word_size, standard]
       
  3430 
       
  3431 lemma slice1_0 [simp] : "slice1 n 0 = 0"
       
  3432   unfolding slice1_def by (simp add : to_bl_0)
       
  3433 
       
  3434 lemma slice_0 [simp] : "slice n 0 = 0"
       
  3435   unfolding slice_def by auto
       
  3436 
       
  3437 lemma slice_take': "slice n w = of_bl (take (size w - n) (to_bl w))"
       
  3438   unfolding slice_def' slice1_def
       
  3439   by (simp add : takefill_alt word_size)
       
  3440 
       
  3441 lemmas slice_take = slice_take' [unfolded word_size]
       
  3442 
       
  3443 -- "shiftr to a word of the same size is just slice, 
       
  3444     slice is just shiftr then ucast"
       
  3445 lemmas shiftr_slice = trans
       
  3446   [OF shiftr_bl [THEN meta_eq_to_obj_eq] slice_take [symmetric], standard]
       
  3447 
       
  3448 lemma slice_shiftr: "slice n w = ucast (w >> n)"
       
  3449   apply (unfold slice_take shiftr_bl)
       
  3450   apply (rule ucast_of_bl_up [symmetric])
       
  3451   apply (simp add: word_size)
       
  3452   done
       
  3453 
       
  3454 lemma nth_slice: 
       
  3455   "(slice n w :: 'a :: len0 word) !! m = 
       
  3456    (w !! (m + n) & m < len_of TYPE ('a))"
       
  3457   unfolding slice_shiftr 
       
  3458   by (simp add : nth_ucast nth_shiftr)
       
  3459 
       
  3460 lemma slice1_down_alt': 
       
  3461   "sl = slice1 n w ==> fs = size sl ==> fs + k = n ==> 
       
  3462     to_bl sl = takefill False fs (drop k (to_bl w))"
       
  3463   unfolding slice1_def word_size of_bl_def uint_bl
       
  3464   by (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop drop_takefill)
       
  3465 
       
  3466 lemma slice1_up_alt': 
       
  3467   "sl = slice1 n w ==> fs = size sl ==> fs = n + k ==> 
       
  3468     to_bl sl = takefill False fs (replicate k False @ (to_bl w))"
       
  3469   apply (unfold slice1_def word_size of_bl_def uint_bl)
       
  3470   apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop 
       
  3471                         takefill_append [symmetric])
       
  3472   apply (rule_tac f = "%k. takefill False (len_of TYPE('a))
       
  3473     (replicate k False @ bin_to_bl (len_of TYPE('b)) (uint w))" in arg_cong)
       
  3474   apply arith
       
  3475   done
       
  3476     
       
  3477 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size]
       
  3478 lemmas su1 = slice1_up_alt' [OF refl refl, unfolded word_size]
       
  3479 lemmas slice1_down_alt = le_add_diff_inverse [THEN sd1]
       
  3480 lemmas slice1_up_alts = 
       
  3481   le_add_diff_inverse [symmetric, THEN su1] 
       
  3482   le_add_diff_inverse2 [symmetric, THEN su1]
       
  3483 
       
  3484 lemma ucast_slice1: "ucast w = slice1 (size w) w"
       
  3485   unfolding slice1_def ucast_bl
       
  3486   by (simp add : takefill_same' word_size)
       
  3487 
       
  3488 lemma ucast_slice: "ucast w = slice 0 w"
       
  3489   unfolding slice_def by (simp add : ucast_slice1)
       
  3490 
       
  3491 lemmas slice_id = trans [OF ucast_slice [symmetric] ucast_id]
       
  3492 
       
  3493 lemma revcast_slice1': 
       
  3494   "rc = revcast w ==> slice1 (size rc) w = rc"
       
  3495   unfolding slice1_def revcast_def' by (simp add : word_size)
       
  3496 
       
  3497 lemmas revcast_slice1 = refl [THEN revcast_slice1']
       
  3498 
       
  3499 lemma slice1_tf_tf': 
       
  3500   "to_bl (slice1 n w :: 'a :: len0 word) = 
       
  3501    rev (takefill False (len_of TYPE('a)) (rev (takefill False n (to_bl w))))"
       
  3502   unfolding slice1_def by (rule word_rev_tf)
       
  3503 
       
  3504 lemmas slice1_tf_tf = slice1_tf_tf'
       
  3505   [THEN word_bl.Rep_inverse', symmetric, standard]
       
  3506 
       
  3507 lemma rev_slice1:
       
  3508   "n + k = len_of TYPE('a) + len_of TYPE('b) \<Longrightarrow> 
       
  3509   slice1 n (word_reverse w :: 'b :: len0 word) = 
       
  3510   word_reverse (slice1 k w :: 'a :: len0 word)"
       
  3511   apply (unfold word_reverse_def slice1_tf_tf)
       
  3512   apply (rule word_bl.Rep_inverse')
       
  3513   apply (rule rev_swap [THEN iffD1])
       
  3514   apply (rule trans [symmetric])
       
  3515   apply (rule tf_rev)
       
  3516    apply (simp add: word_bl.Abs_inverse)
       
  3517   apply (simp add: word_bl.Abs_inverse)
       
  3518   done
       
  3519 
       
  3520 lemma rev_slice': 
       
  3521   "res = slice n (word_reverse w) ==> n + k + size res = size w ==> 
       
  3522     res = word_reverse (slice k w)"
       
  3523   apply (unfold slice_def word_size)
       
  3524   apply clarify
       
  3525   apply (rule rev_slice1)
       
  3526   apply arith
       
  3527   done
       
  3528 
       
  3529 lemmas rev_slice = refl [THEN rev_slice', unfolded word_size]
       
  3530 
       
  3531 lemmas sym_notr = 
       
  3532   not_iff [THEN iffD2, THEN not_sym, THEN not_iff [THEN iffD1]]
       
  3533 
       
  3534 -- {* problem posed by TPHOLs referee:
       
  3535       criterion for overflow of addition of signed integers *}
       
  3536 
       
  3537 lemma sofl_test:
       
  3538   "(sint (x :: 'a :: len word) + sint y = sint (x + y)) = 
       
  3539      ((((x+y) XOR x) AND ((x+y) XOR y)) >> (size x - 1) = 0)"
       
  3540   apply (unfold word_size)
       
  3541   apply (cases "len_of TYPE('a)", simp) 
       
  3542   apply (subst msb_shift [THEN sym_notr])
       
  3543   apply (simp add: word_ops_msb)
       
  3544   apply (simp add: word_msb_sint)
       
  3545   apply safe
       
  3546        apply simp_all
       
  3547      apply (unfold sint_word_ariths)
       
  3548      apply (unfold word_sbin.set_iff_norm [symmetric] sints_num)
       
  3549      apply safe
       
  3550         apply (insert sint_range' [where x=x])
       
  3551         apply (insert sint_range' [where x=y])
       
  3552         defer 
       
  3553         apply (simp (no_asm), arith)
       
  3554        apply (simp (no_asm), arith)
       
  3555       defer
       
  3556       defer
       
  3557       apply (simp (no_asm), arith)
       
  3558      apply (simp (no_asm), arith)
       
  3559     apply (rule notI [THEN notnotD],
       
  3560            drule leI not_leE,
       
  3561            drule sbintrunc_inc sbintrunc_dec,      
       
  3562            simp)+
       
  3563   done
       
  3564 
       
  3565 
       
  3566 subsection "Split and cat"
       
  3567 
       
  3568 lemmas word_split_bin' = word_split_def [THEN meta_eq_to_obj_eq, standard]
       
  3569 lemmas word_cat_bin' = word_cat_def [THEN meta_eq_to_obj_eq, standard]
       
  3570 
       
  3571 lemma word_rsplit_no:
       
  3572   "(word_rsplit (number_of bin :: 'b :: len0 word) :: 'a word list) = 
       
  3573     map number_of (bin_rsplit (len_of TYPE('a :: len)) 
       
  3574       (len_of TYPE('b), bintrunc (len_of TYPE('b)) bin))"
       
  3575   apply (unfold word_rsplit_def word_no_wi)
       
  3576   apply (simp add: word_ubin.eq_norm)
       
  3577   done
       
  3578 
       
  3579 lemmas word_rsplit_no_cl [simp] = word_rsplit_no
       
  3580   [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]]
       
  3581 
       
  3582 lemma test_bit_cat:
       
  3583   "wc = word_cat a b ==> wc !! n = (n < size wc & 
       
  3584     (if n < size b then b !! n else a !! (n - size b)))"
       
  3585   apply (unfold word_cat_bin' test_bit_bin)
       
  3586   apply (auto simp add : word_ubin.eq_norm nth_bintr bin_nth_cat word_size)
       
  3587   apply (erule bin_nth_uint_imp)
       
  3588   done
       
  3589 
       
  3590 lemma word_cat_bl: "word_cat a b = of_bl (to_bl a @ to_bl b)"
       
  3591   apply (unfold of_bl_def to_bl_def word_cat_bin')
       
  3592   apply (simp add: bl_to_bin_app_cat)
       
  3593   done
       
  3594 
       
  3595 lemma of_bl_append:
       
  3596   "(of_bl (xs @ ys) :: 'a :: len word) = of_bl xs * 2^(length ys) + of_bl ys"
       
  3597   apply (unfold of_bl_def)
       
  3598   apply (simp add: bl_to_bin_app_cat bin_cat_num)
       
  3599   apply (simp add: word_of_int_power_hom [symmetric] new_word_of_int_hom_syms)
       
  3600   done
       
  3601 
       
  3602 lemma of_bl_False [simp]:
       
  3603   "of_bl (False#xs) = of_bl xs"
       
  3604   by (rule word_eqI)
       
  3605      (auto simp add: test_bit_of_bl nth_append)
       
  3606 
       
  3607 lemma of_bl_True: 
       
  3608   "(of_bl (True#xs)::'a::len word) = 2^length xs + of_bl xs"
       
  3609   by (subst of_bl_append [where xs="[True]", simplified])
       
  3610      (simp add: word_1_bl)
       
  3611 
       
  3612 lemma of_bl_Cons:
       
  3613   "of_bl (x#xs) = of_bool x * 2^length xs + of_bl xs"
       
  3614   by (cases x) (simp_all add: of_bl_True)
       
  3615 
       
  3616 lemma split_uint_lem: "bin_split n (uint (w :: 'a :: len0 word)) = (a, b) ==> 
       
  3617   a = bintrunc (len_of TYPE('a) - n) a & b = bintrunc (len_of TYPE('a)) b"
       
  3618   apply (frule word_ubin.norm_Rep [THEN ssubst])
       
  3619   apply (drule bin_split_trunc1)
       
  3620   apply (drule sym [THEN trans])
       
  3621   apply assumption
       
  3622   apply safe
       
  3623   done
       
  3624 
       
  3625 lemma word_split_bl': 
       
  3626   "std = size c - size b ==> (word_split c = (a, b)) ==> 
       
  3627     (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c)))"
       
  3628   apply (unfold word_split_bin')
       
  3629   apply safe
       
  3630    defer
       
  3631    apply (clarsimp split: prod.splits)
       
  3632    apply (drule word_ubin.norm_Rep [THEN ssubst])
       
  3633    apply (drule split_bintrunc)
       
  3634    apply (simp add : of_bl_def bl2bin_drop word_size
       
  3635        word_ubin.norm_eq_iff [symmetric] min_def del : word_ubin.norm_Rep)    
       
  3636   apply (clarsimp split: prod.splits)
       
  3637   apply (frule split_uint_lem [THEN conjunct1])
       
  3638   apply (unfold word_size)
       
  3639   apply (cases "len_of TYPE('a) >= len_of TYPE('b)")
       
  3640    defer
       
  3641    apply (simp add: word_0_bl word_0_wi_Pls)
       
  3642   apply (simp add : of_bl_def to_bl_def)
       
  3643   apply (subst bin_split_take1 [symmetric])
       
  3644     prefer 2
       
  3645     apply assumption
       
  3646    apply simp
       
  3647   apply (erule thin_rl)
       
  3648   apply (erule arg_cong [THEN trans])
       
  3649   apply (simp add : word_ubin.norm_eq_iff [symmetric])
       
  3650   done
       
  3651 
       
  3652 lemma word_split_bl: "std = size c - size b ==> 
       
  3653     (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c))) <-> 
       
  3654     word_split c = (a, b)"
       
  3655   apply (rule iffI)
       
  3656    defer
       
  3657    apply (erule (1) word_split_bl')
       
  3658   apply (case_tac "word_split c")
       
  3659   apply (auto simp add : word_size)
       
  3660   apply (frule word_split_bl' [rotated])
       
  3661   apply (auto simp add : word_size)
       
  3662   done
       
  3663 
       
  3664 lemma word_split_bl_eq:
       
  3665    "(word_split (c::'a::len word) :: ('c :: len0 word * 'd :: len0 word)) =
       
  3666       (of_bl (take (len_of TYPE('a::len) - len_of TYPE('d::len0)) (to_bl c)),
       
  3667        of_bl (drop (len_of TYPE('a) - len_of TYPE('d)) (to_bl c)))"
       
  3668   apply (rule word_split_bl [THEN iffD1])
       
  3669   apply (unfold word_size)
       
  3670   apply (rule refl conjI)+
       
  3671   done
       
  3672 
       
  3673 -- "keep quantifiers for use in simplification"
       
  3674 lemma test_bit_split':
       
  3675   "word_split c = (a, b) --> (ALL n m. b !! n = (n < size b & c !! n) & 
       
  3676     a !! m = (m < size a & c !! (m + size b)))"
       
  3677   apply (unfold word_split_bin' test_bit_bin)
       
  3678   apply (clarify)
       
  3679   apply (clarsimp simp: word_ubin.eq_norm nth_bintr word_size split: prod.splits)
       
  3680   apply (drule bin_nth_split)
       
  3681   apply safe
       
  3682        apply (simp_all add: add_commute)
       
  3683    apply (erule bin_nth_uint_imp)+
       
  3684   done
       
  3685 
       
  3686 lemma test_bit_split:
       
  3687   "word_split c = (a, b) \<Longrightarrow>
       
  3688     (\<forall>n\<Colon>nat. b !! n \<longleftrightarrow> n < size b \<and> c !! n) \<and> (\<forall>m\<Colon>nat. a !! m \<longleftrightarrow> m < size a \<and> c !! (m + size b))"
       
  3689   by (simp add: test_bit_split')
       
  3690 
       
  3691 lemma test_bit_split_eq: "word_split c = (a, b) <-> 
       
  3692   ((ALL n::nat. b !! n = (n < size b & c !! n)) &
       
  3693     (ALL m::nat. a !! m = (m < size a & c !! (m + size b))))"
       
  3694   apply (rule_tac iffI)
       
  3695    apply (rule_tac conjI)
       
  3696     apply (erule test_bit_split [THEN conjunct1])
       
  3697    apply (erule test_bit_split [THEN conjunct2])
       
  3698   apply (case_tac "word_split c")
       
  3699   apply (frule test_bit_split)
       
  3700   apply (erule trans)
       
  3701   apply (fastsimp intro ! : word_eqI simp add : word_size)
       
  3702   done
       
  3703 
       
  3704 -- {* this odd result is analogous to @{text "ucast_id"}, 
       
  3705       result to the length given by the result type *}
       
  3706 
       
  3707 lemma word_cat_id: "word_cat a b = b"
       
  3708   unfolding word_cat_bin' by (simp add: word_ubin.inverse_norm)
       
  3709 
       
  3710 -- "limited hom result"
       
  3711 lemma word_cat_hom:
       
  3712   "len_of TYPE('a::len0) <= len_of TYPE('b::len0) + len_of TYPE ('c::len0)
       
  3713   ==>
       
  3714   (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) = 
       
  3715   word_of_int (bin_cat w (size b) (uint b))"
       
  3716   apply (unfold word_cat_def word_size) 
       
  3717   apply (clarsimp simp add: word_ubin.norm_eq_iff [symmetric]
       
  3718       word_ubin.eq_norm bintr_cat min_max.inf_absorb1)
       
  3719   done
       
  3720 
       
  3721 lemma word_cat_split_alt:
       
  3722   "size w <= size u + size v ==> word_split w = (u, v) ==> word_cat u v = w"
       
  3723   apply (rule word_eqI)
       
  3724   apply (drule test_bit_split)
       
  3725   apply (clarsimp simp add : test_bit_cat word_size)
       
  3726   apply safe
       
  3727   apply arith
       
  3728   done
       
  3729 
       
  3730 lemmas word_cat_split_size = 
       
  3731   sym [THEN [2] word_cat_split_alt [symmetric], standard]
       
  3732 
       
  3733 
       
  3734 subsubsection "Split and slice"
       
  3735 
       
  3736 lemma split_slices: 
       
  3737   "word_split w = (u, v) ==> u = slice (size v) w & v = slice 0 w"
       
  3738   apply (drule test_bit_split)
       
  3739   apply (rule conjI)
       
  3740    apply (rule word_eqI, clarsimp simp: nth_slice word_size)+
       
  3741   done
       
  3742 
       
  3743 lemma slice_cat1':
       
  3744   "wc = word_cat a b ==> size wc >= size a + size b ==> slice (size b) wc = a"
       
  3745   apply safe
       
  3746   apply (rule word_eqI)
       
  3747   apply (simp add: nth_slice test_bit_cat word_size)
       
  3748   done
       
  3749 
       
  3750 lemmas slice_cat1 = refl [THEN slice_cat1']
       
  3751 lemmas slice_cat2 = trans [OF slice_id word_cat_id]
       
  3752 
       
  3753 lemma cat_slices:
       
  3754   "a = slice n c ==> b = slice 0 c ==> n = size b ==>
       
  3755     size a + size b >= size c ==> word_cat a b = c"
       
  3756   apply safe
       
  3757   apply (rule word_eqI)
       
  3758   apply (simp add: nth_slice test_bit_cat word_size)
       
  3759   apply safe
       
  3760   apply arith
       
  3761   done
       
  3762 
       
  3763 lemma word_split_cat_alt:
       
  3764   "w = word_cat u v ==> size u + size v <= size w ==> word_split w = (u, v)"
       
  3765   apply (case_tac "word_split ?w")
       
  3766   apply (rule trans, assumption)
       
  3767   apply (drule test_bit_split)
       
  3768   apply safe
       
  3769    apply (rule word_eqI, clarsimp simp: test_bit_cat word_size)+
       
  3770   done
       
  3771 
       
  3772 lemmas word_cat_bl_no_bin [simp] =
       
  3773   word_cat_bl [where a="number_of a" 
       
  3774                  and b="number_of b", 
       
  3775                unfolded to_bl_no_bin, standard]
       
  3776 
       
  3777 lemmas word_split_bl_no_bin [simp] =
       
  3778   word_split_bl_eq [where c="number_of c", unfolded to_bl_no_bin, standard]
       
  3779 
       
  3780 -- {* this odd result arises from the fact that the statement of the
       
  3781       result implies that the decoded words are of the same type, 
       
  3782       and therefore of the same length, as the original word *}
       
  3783 
       
  3784 lemma word_rsplit_same: "word_rsplit w = [w]"
       
  3785   unfolding word_rsplit_def by (simp add : bin_rsplit_all)
       
  3786 
       
  3787 lemma word_rsplit_empty_iff_size:
       
  3788   "(word_rsplit w = []) = (size w = 0)" 
       
  3789   unfolding word_rsplit_def bin_rsplit_def word_size
       
  3790   by (simp add: bin_rsplit_aux_simp_alt Let_def split: Product_Type.split_split)
       
  3791 
       
  3792 lemma test_bit_rsplit:
       
  3793   "sw = word_rsplit w ==> m < size (hd sw :: 'a :: len word) ==> 
       
  3794     k < length sw ==> (rev sw ! k) !! m = (w !! (k * size (hd sw) + m))"
       
  3795   apply (unfold word_rsplit_def word_test_bit_def)
       
  3796   apply (rule trans)
       
  3797    apply (rule_tac f = "%x. bin_nth x m" in arg_cong)
       
  3798    apply (rule nth_map [symmetric])
       
  3799    apply simp
       
  3800   apply (rule bin_nth_rsplit)
       
  3801      apply simp_all
       
  3802   apply (simp add : word_size rev_map)
       
  3803   apply (rule trans)
       
  3804    defer
       
  3805    apply (rule map_ident [THEN fun_cong])
       
  3806   apply (rule refl [THEN map_cong])
       
  3807   apply (simp add : word_ubin.eq_norm)
       
  3808   apply (erule bin_rsplit_size_sign [OF len_gt_0 refl])
       
  3809   done
       
  3810 
       
  3811 lemma word_rcat_bl: "word_rcat wl == of_bl (concat (map to_bl wl))"
       
  3812   unfolding word_rcat_def to_bl_def' of_bl_def
       
  3813   by (clarsimp simp add : bin_rcat_bl)
       
  3814 
       
  3815 lemma size_rcat_lem':
       
  3816   "size (concat (map to_bl wl)) = length wl * size (hd wl)"
       
  3817   unfolding word_size by (induct wl) auto
       
  3818 
       
  3819 lemmas size_rcat_lem = size_rcat_lem' [unfolded word_size]
       
  3820 
       
  3821 lemmas td_gal_lt_len = len_gt_0 [THEN td_gal_lt, standard]
       
  3822 
       
  3823 lemma nth_rcat_lem' [rule_format] :
       
  3824   "sw = size (hd wl  :: 'a :: len word) ==> (ALL n. n < size wl * sw --> 
       
  3825     rev (concat (map to_bl wl)) ! n = 
       
  3826     rev (to_bl (rev wl ! (n div sw))) ! (n mod sw))"
       
  3827   apply (unfold word_size)
       
  3828   apply (induct "wl")
       
  3829    apply clarsimp
       
  3830   apply (clarsimp simp add : nth_append size_rcat_lem)
       
  3831   apply (simp (no_asm_use) only:  mult_Suc [symmetric] 
       
  3832          td_gal_lt_len less_Suc_eq_le mod_div_equality')
       
  3833   apply clarsimp
       
  3834   done
       
  3835 
       
  3836 lemmas nth_rcat_lem = refl [THEN nth_rcat_lem', unfolded word_size]
       
  3837 
       
  3838 lemma test_bit_rcat:
       
  3839   "sw = size (hd wl :: 'a :: len word) ==> rc = word_rcat wl ==> rc !! n = 
       
  3840     (n < size rc & n div sw < size wl & (rev wl) ! (n div sw) !! (n mod sw))"
       
  3841   apply (unfold word_rcat_bl word_size)
       
  3842   apply (clarsimp simp add : 
       
  3843     test_bit_of_bl size_rcat_lem word_size td_gal_lt_len)
       
  3844   apply safe
       
  3845    apply (auto simp add : 
       
  3846     test_bit_bl word_size td_gal_lt_len [THEN iffD2, THEN nth_rcat_lem])
       
  3847   done
       
  3848 
       
  3849 lemma foldl_eq_foldr [rule_format] :
       
  3850   "ALL x. foldl op + x xs = foldr op + (x # xs) (0 :: 'a :: comm_monoid_add)" 
       
  3851   by (induct xs) (auto simp add : add_assoc)
       
  3852 
       
  3853 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong]
       
  3854 
       
  3855 lemmas test_bit_rsplit_alt = 
       
  3856   trans [OF nth_rev_alt [THEN test_bit_cong] 
       
  3857   test_bit_rsplit [OF refl asm_rl diff_Suc_less]]
       
  3858 
       
  3859 -- "lazy way of expressing that u and v, and su and sv, have same types"
       
  3860 lemma word_rsplit_len_indep':
       
  3861   "[u,v] = p ==> [su,sv] = q ==> word_rsplit u = su ==> 
       
  3862     word_rsplit v = sv ==> length su = length sv"
       
  3863   apply (unfold word_rsplit_def)
       
  3864   apply (auto simp add : bin_rsplit_len_indep)
       
  3865   done
       
  3866 
       
  3867 lemmas word_rsplit_len_indep = word_rsplit_len_indep' [OF refl refl refl refl]
       
  3868 
       
  3869 lemma length_word_rsplit_size: 
       
  3870   "n = len_of TYPE ('a :: len) ==> 
       
  3871     (length (word_rsplit w :: 'a word list) <= m) = (size w <= m * n)"
       
  3872   apply (unfold word_rsplit_def word_size)
       
  3873   apply (clarsimp simp add : bin_rsplit_len_le)
       
  3874   done
       
  3875 
       
  3876 lemmas length_word_rsplit_lt_size = 
       
  3877   length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]]
       
  3878 
       
  3879 lemma length_word_rsplit_exp_size: 
       
  3880   "n = len_of TYPE ('a :: len) ==> 
       
  3881     length (word_rsplit w :: 'a word list) = (size w + n - 1) div n"
       
  3882   unfolding word_rsplit_def by (clarsimp simp add : word_size bin_rsplit_len)
       
  3883 
       
  3884 lemma length_word_rsplit_even_size: 
       
  3885   "n = len_of TYPE ('a :: len) ==> size w = m * n ==> 
       
  3886     length (word_rsplit w :: 'a word list) = m"
       
  3887   by (clarsimp simp add : length_word_rsplit_exp_size given_quot_alt)
       
  3888 
       
  3889 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size]
       
  3890 
       
  3891 (* alternative proof of word_rcat_rsplit *)
       
  3892 lemmas tdle = iffD2 [OF split_div_lemma refl, THEN conjunct1] 
       
  3893 lemmas dtle = xtr4 [OF tdle mult_commute]
       
  3894 
       
  3895 lemma word_rcat_rsplit: "word_rcat (word_rsplit w) = w"
       
  3896   apply (rule word_eqI)
       
  3897   apply (clarsimp simp add : test_bit_rcat word_size)
       
  3898   apply (subst refl [THEN test_bit_rsplit])
       
  3899     apply (simp_all add: word_size 
       
  3900       refl [THEN length_word_rsplit_size [simplified not_less [symmetric], simplified]])
       
  3901    apply safe
       
  3902    apply (erule xtr7, rule len_gt_0 [THEN dtle])+
       
  3903   done
       
  3904 
       
  3905 lemma size_word_rsplit_rcat_size':
       
  3906   "word_rcat (ws :: 'a :: len word list) = frcw ==> 
       
  3907     size frcw = length ws * len_of TYPE ('a) ==> 
       
  3908     size (hd [word_rsplit frcw, ws]) = size ws" 
       
  3909   apply (clarsimp simp add : word_size length_word_rsplit_exp_size')
       
  3910   apply (fast intro: given_quot_alt)
       
  3911   done
       
  3912 
       
  3913 lemmas size_word_rsplit_rcat_size = 
       
  3914   size_word_rsplit_rcat_size' [simplified]
       
  3915 
       
  3916 lemma msrevs:
       
  3917   fixes n::nat
       
  3918   shows "0 < n \<Longrightarrow> (k * n + m) div n = m div n + k"
       
  3919   and   "(k * n + m) mod n = m mod n"
       
  3920   by (auto simp: add_commute)
       
  3921 
       
  3922 lemma word_rsplit_rcat_size':
       
  3923   "word_rcat (ws :: 'a :: len word list) = frcw ==> 
       
  3924     size frcw = length ws * len_of TYPE ('a) ==> word_rsplit frcw = ws" 
       
  3925   apply (frule size_word_rsplit_rcat_size, assumption)
       
  3926   apply (clarsimp simp add : word_size)
       
  3927   apply (rule nth_equalityI, assumption)
       
  3928   apply clarsimp
       
  3929   apply (rule word_eqI)
       
  3930   apply (rule trans)
       
  3931    apply (rule test_bit_rsplit_alt)
       
  3932      apply (clarsimp simp: word_size)+
       
  3933   apply (rule trans)
       
  3934   apply (rule test_bit_rcat [OF refl refl])
       
  3935   apply (simp add : word_size msrevs)
       
  3936   apply (subst nth_rev)
       
  3937    apply arith
       
  3938   apply (simp add : le0 [THEN [2] xtr7, THEN diff_Suc_less])
       
  3939   apply safe
       
  3940   apply (simp add : diff_mult_distrib)
       
  3941   apply (rule mpl_lem)
       
  3942   apply (cases "size ws")
       
  3943    apply simp_all
       
  3944   done
       
  3945 
       
  3946 lemmas word_rsplit_rcat_size = refl [THEN word_rsplit_rcat_size']
       
  3947 
       
  3948 
       
  3949 subsection "Rotation"
       
  3950 
       
  3951 lemmas rotater_0' [simp] = rotater_def [where n = "0", simplified]
       
  3952 
       
  3953 lemmas word_rot_defs = word_roti_def word_rotr_def word_rotl_def
       
  3954 
       
  3955 lemma rotate_eq_mod: 
       
  3956   "m mod length xs = n mod length xs ==> rotate m xs = rotate n xs"
       
  3957   apply (rule box_equals)
       
  3958     defer
       
  3959     apply (rule rotate_conv_mod [symmetric])+
       
  3960   apply simp
       
  3961   done
       
  3962 
       
  3963 lemmas rotate_eqs [standard] = 
       
  3964   trans [OF rotate0 [THEN fun_cong] id_apply]
       
  3965   rotate_rotate [symmetric] 
       
  3966   rotate_id 
       
  3967   rotate_conv_mod 
       
  3968   rotate_eq_mod
       
  3969 
       
  3970 
       
  3971 subsubsection "Rotation of list to right"
       
  3972 
       
  3973 lemma rotate1_rl': "rotater1 (l @ [a]) = a # l"
       
  3974   unfolding rotater1_def by (cases l) auto
       
  3975 
       
  3976 lemma rotate1_rl [simp] : "rotater1 (rotate1 l) = l"
       
  3977   apply (unfold rotater1_def)
       
  3978   apply (cases "l")
       
  3979   apply (case_tac [2] "list")
       
  3980   apply auto
       
  3981   done
       
  3982 
       
  3983 lemma rotate1_lr [simp] : "rotate1 (rotater1 l) = l"
       
  3984   unfolding rotater1_def by (cases l) auto
       
  3985 
       
  3986 lemma rotater1_rev': "rotater1 (rev xs) = rev (rotate1 xs)"
       
  3987   apply (cases "xs")
       
  3988   apply (simp add : rotater1_def)
       
  3989   apply (simp add : rotate1_rl')
       
  3990   done
       
  3991   
       
  3992 lemma rotater_rev': "rotater n (rev xs) = rev (rotate n xs)"
       
  3993   unfolding rotater_def by (induct n) (auto intro: rotater1_rev')
       
  3994 
       
  3995 lemmas rotater_rev = rotater_rev' [where xs = "rev ys", simplified, standard]
       
  3996 
       
  3997 lemma rotater_drop_take: 
       
  3998   "rotater n xs = 
       
  3999    drop (length xs - n mod length xs) xs @
       
  4000    take (length xs - n mod length xs) xs"
       
  4001   by (clarsimp simp add : rotater_rev rotate_drop_take rev_take rev_drop)
       
  4002 
       
  4003 lemma rotater_Suc [simp] : 
       
  4004   "rotater (Suc n) xs = rotater1 (rotater n xs)"
       
  4005   unfolding rotater_def by auto
       
  4006 
       
  4007 lemma rotate_inv_plus [rule_format] :
       
  4008   "ALL k. k = m + n --> rotater k (rotate n xs) = rotater m xs & 
       
  4009     rotate k (rotater n xs) = rotate m xs & 
       
  4010     rotater n (rotate k xs) = rotate m xs & 
       
  4011     rotate n (rotater k xs) = rotater m xs"
       
  4012   unfolding rotater_def rotate_def
       
  4013   by (induct n) (auto intro: funpow_swap1 [THEN trans])
       
  4014   
       
  4015 lemmas rotate_inv_rel = le_add_diff_inverse2 [symmetric, THEN rotate_inv_plus]
       
  4016 
       
  4017 lemmas rotate_inv_eq = order_refl [THEN rotate_inv_rel, simplified]
       
  4018 
       
  4019 lemmas rotate_lr [simp] = rotate_inv_eq [THEN conjunct1, standard]
       
  4020 lemmas rotate_rl [simp] =
       
  4021   rotate_inv_eq [THEN conjunct2, THEN conjunct1, standard]
       
  4022 
       
  4023 lemma rotate_gal: "(rotater n xs = ys) = (rotate n ys = xs)"
       
  4024   by auto
       
  4025 
       
  4026 lemma rotate_gal': "(ys = rotater n xs) = (xs = rotate n ys)"
       
  4027   by auto
       
  4028 
       
  4029 lemma length_rotater [simp]: 
       
  4030   "length (rotater n xs) = length xs"
       
  4031   by (simp add : rotater_rev)
       
  4032 
       
  4033 lemmas rrs0 = rotate_eqs [THEN restrict_to_left, 
       
  4034   simplified rotate_gal [symmetric] rotate_gal' [symmetric], standard]
       
  4035 lemmas rrs1 = rrs0 [THEN refl [THEN rev_iffD1]]
       
  4036 lemmas rotater_eqs = rrs1 [simplified length_rotater, standard]
       
  4037 lemmas rotater_0 = rotater_eqs (1)
       
  4038 lemmas rotater_add = rotater_eqs (2)
       
  4039 
       
  4040 
       
  4041 subsubsection "map, map2, commuting with rotate(r)"
       
  4042 
       
  4043 lemma last_map: "xs ~= [] ==> last (map f xs) = f (last xs)"
       
  4044   by (induct xs) auto
       
  4045 
       
  4046 lemma butlast_map:
       
  4047   "xs ~= [] ==> butlast (map f xs) = map f (butlast xs)"
       
  4048   by (induct xs) auto
       
  4049 
       
  4050 lemma rotater1_map: "rotater1 (map f xs) = map f (rotater1 xs)" 
       
  4051   unfolding rotater1_def
       
  4052   by (cases xs) (auto simp add: last_map butlast_map)
       
  4053 
       
  4054 lemma rotater_map:
       
  4055   "rotater n (map f xs) = map f (rotater n xs)" 
       
  4056   unfolding rotater_def
       
  4057   by (induct n) (auto simp add : rotater1_map)
       
  4058 
       
  4059 lemma but_last_zip [rule_format] :
       
  4060   "ALL ys. length xs = length ys --> xs ~= [] --> 
       
  4061     last (zip xs ys) = (last xs, last ys) & 
       
  4062     butlast (zip xs ys) = zip (butlast xs) (butlast ys)" 
       
  4063   apply (induct "xs")
       
  4064   apply auto
       
  4065      apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
       
  4066   done
       
  4067 
       
  4068 lemma but_last_map2 [rule_format] :
       
  4069   "ALL ys. length xs = length ys --> xs ~= [] --> 
       
  4070     last (map2 f xs ys) = f (last xs) (last ys) & 
       
  4071     butlast (map2 f xs ys) = map2 f (butlast xs) (butlast ys)" 
       
  4072   apply (induct "xs")
       
  4073   apply auto
       
  4074      apply (unfold map2_def)
       
  4075      apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
       
  4076   done
       
  4077 
       
  4078 lemma rotater1_zip:
       
  4079   "length xs = length ys ==> 
       
  4080     rotater1 (zip xs ys) = zip (rotater1 xs) (rotater1 ys)" 
       
  4081   apply (unfold rotater1_def)
       
  4082   apply (cases "xs")
       
  4083    apply auto
       
  4084    apply ((case_tac ys, auto simp: neq_Nil_conv but_last_zip)[1])+
       
  4085   done
       
  4086 
       
  4087 lemma rotater1_map2:
       
  4088   "length xs = length ys ==> 
       
  4089     rotater1 (map2 f xs ys) = map2 f (rotater1 xs) (rotater1 ys)" 
       
  4090   unfolding map2_def by (simp add: rotater1_map rotater1_zip)
       
  4091 
       
  4092 lemmas lrth = 
       
  4093   box_equals [OF asm_rl length_rotater [symmetric] 
       
  4094                  length_rotater [symmetric], 
       
  4095               THEN rotater1_map2]
       
  4096 
       
  4097 lemma rotater_map2: 
       
  4098   "length xs = length ys ==> 
       
  4099     rotater n (map2 f xs ys) = map2 f (rotater n xs) (rotater n ys)" 
       
  4100   by (induct n) (auto intro!: lrth)
       
  4101 
       
  4102 lemma rotate1_map2:
       
  4103   "length xs = length ys ==> 
       
  4104     rotate1 (map2 f xs ys) = map2 f (rotate1 xs) (rotate1 ys)" 
       
  4105   apply (unfold map2_def)
       
  4106   apply (cases xs)
       
  4107    apply (cases ys, auto simp add : rotate1_def)+
       
  4108   done
       
  4109 
       
  4110 lemmas lth = box_equals [OF asm_rl length_rotate [symmetric] 
       
  4111   length_rotate [symmetric], THEN rotate1_map2]
       
  4112 
       
  4113 lemma rotate_map2: 
       
  4114   "length xs = length ys ==> 
       
  4115     rotate n (map2 f xs ys) = map2 f (rotate n xs) (rotate n ys)" 
       
  4116   by (induct n) (auto intro!: lth)
       
  4117 
       
  4118 
       
  4119 -- "corresponding equalities for word rotation"
       
  4120 
       
  4121 lemma to_bl_rotl: 
       
  4122   "to_bl (word_rotl n w) = rotate n (to_bl w)"
       
  4123   by (simp add: word_bl.Abs_inverse' word_rotl_def)
       
  4124 
       
  4125 lemmas blrs0 = rotate_eqs [THEN to_bl_rotl [THEN trans]]
       
  4126 
       
  4127 lemmas word_rotl_eqs =
       
  4128   blrs0 [simplified word_bl.Rep' word_bl.Rep_inject to_bl_rotl [symmetric]]
       
  4129 
       
  4130 lemma to_bl_rotr: 
       
  4131   "to_bl (word_rotr n w) = rotater n (to_bl w)"
       
  4132   by (simp add: word_bl.Abs_inverse' word_rotr_def)
       
  4133 
       
  4134 lemmas brrs0 = rotater_eqs [THEN to_bl_rotr [THEN trans]]
       
  4135 
       
  4136 lemmas word_rotr_eqs =
       
  4137   brrs0 [simplified word_bl.Rep' word_bl.Rep_inject to_bl_rotr [symmetric]]
       
  4138 
       
  4139 declare word_rotr_eqs (1) [simp]
       
  4140 declare word_rotl_eqs (1) [simp]
       
  4141 
       
  4142 lemma
       
  4143   word_rot_rl [simp]:
       
  4144   "word_rotl k (word_rotr k v) = v" and
       
  4145   word_rot_lr [simp]:
       
  4146   "word_rotr k (word_rotl k v) = v"
       
  4147   by (auto simp add: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric])
       
  4148 
       
  4149 lemma
       
  4150   word_rot_gal:
       
  4151   "(word_rotr n v = w) = (word_rotl n w = v)" and
       
  4152   word_rot_gal':
       
  4153   "(w = word_rotr n v) = (v = word_rotl n w)"
       
  4154   by (auto simp: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric] 
       
  4155            dest: sym)
       
  4156 
       
  4157 lemma word_rotr_rev:
       
  4158   "word_rotr n w = word_reverse (word_rotl n (word_reverse w))"
       
  4159   by (simp add: word_bl.Rep_inject [symmetric] to_bl_word_rev
       
  4160                 to_bl_rotr to_bl_rotl rotater_rev)
       
  4161   
       
  4162 lemma word_roti_0 [simp]: "word_roti 0 w = w"
       
  4163   by (unfold word_rot_defs) auto
       
  4164 
       
  4165 lemmas abl_cong = arg_cong [where f = "of_bl"]
       
  4166 
       
  4167 lemma word_roti_add: 
       
  4168   "word_roti (m + n) w = word_roti m (word_roti n w)"
       
  4169 proof -
       
  4170   have rotater_eq_lem: 
       
  4171     "\<And>m n xs. m = n ==> rotater m xs = rotater n xs"
       
  4172     by auto
       
  4173 
       
  4174   have rotate_eq_lem: 
       
  4175     "\<And>m n xs. m = n ==> rotate m xs = rotate n xs"
       
  4176     by auto
       
  4177 
       
  4178   note rpts [symmetric, standard] = 
       
  4179     rotate_inv_plus [THEN conjunct1]
       
  4180     rotate_inv_plus [THEN conjunct2, THEN conjunct1]
       
  4181     rotate_inv_plus [THEN conjunct2, THEN conjunct2, THEN conjunct1]
       
  4182     rotate_inv_plus [THEN conjunct2, THEN conjunct2, THEN conjunct2]
       
  4183 
       
  4184   note rrp = trans [symmetric, OF rotate_rotate rotate_eq_lem]
       
  4185   note rrrp = trans [symmetric, OF rotater_add [symmetric] rotater_eq_lem]
       
  4186 
       
  4187   show ?thesis
       
  4188   apply (unfold word_rot_defs)
       
  4189   apply (simp only: split: split_if)
       
  4190   apply (safe intro!: abl_cong)
       
  4191   apply (simp_all only: to_bl_rotl [THEN word_bl.Rep_inverse'] 
       
  4192                     to_bl_rotl
       
  4193                     to_bl_rotr [THEN word_bl.Rep_inverse']
       
  4194                     to_bl_rotr)
       
  4195   apply (rule rrp rrrp rpts,
       
  4196          simp add: nat_add_distrib [symmetric] 
       
  4197                    nat_diff_distrib [symmetric])+
       
  4198   done
       
  4199 qed
       
  4200     
       
  4201 lemma word_roti_conv_mod': "word_roti n w = word_roti (n mod int (size w)) w"
       
  4202   apply (unfold word_rot_defs)
       
  4203   apply (cut_tac y="size w" in gt_or_eq_0)
       
  4204   apply (erule disjE)
       
  4205    apply simp_all
       
  4206   apply (safe intro!: abl_cong)
       
  4207    apply (rule rotater_eqs)
       
  4208    apply (simp add: word_size nat_mod_distrib)
       
  4209   apply (simp add: rotater_add [symmetric] rotate_gal [symmetric])
       
  4210   apply (rule rotater_eqs)
       
  4211   apply (simp add: word_size nat_mod_distrib)
       
  4212   apply (rule int_eq_0_conv [THEN iffD1])
       
  4213   apply (simp only: zmod_int zadd_int [symmetric])
       
  4214   apply (simp add: rdmods)
       
  4215   done
       
  4216 
       
  4217 lemmas word_roti_conv_mod = word_roti_conv_mod' [unfolded word_size]
       
  4218 
       
  4219 
       
  4220 subsubsection "Word rotation commutes with bit-wise operations"
       
  4221 
       
  4222 (* using locale to not pollute lemma namespace *)
       
  4223 locale word_rotate 
       
  4224 
       
  4225 context word_rotate
       
  4226 begin
       
  4227 
       
  4228 lemmas word_rot_defs' = to_bl_rotl to_bl_rotr
       
  4229 
       
  4230 lemmas blwl_syms [symmetric] = bl_word_not bl_word_and bl_word_or bl_word_xor
       
  4231 
       
  4232 lemmas lbl_lbl = trans [OF word_bl.Rep' word_bl.Rep' [symmetric]]
       
  4233 
       
  4234 lemmas ths_map2 [OF lbl_lbl] = rotate_map2 rotater_map2
       
  4235 
       
  4236 lemmas ths_map [where xs = "to_bl v", standard] = rotate_map rotater_map
       
  4237 
       
  4238 lemmas th1s [simplified word_rot_defs' [symmetric]] = ths_map2 ths_map
       
  4239 
       
  4240 lemma word_rot_logs:
       
  4241   "word_rotl n (NOT v) = NOT word_rotl n v"
       
  4242   "word_rotr n (NOT v) = NOT word_rotr n v"
       
  4243   "word_rotl n (x AND y) = word_rotl n x AND word_rotl n y"
       
  4244   "word_rotr n (x AND y) = word_rotr n x AND word_rotr n y"
       
  4245   "word_rotl n (x OR y) = word_rotl n x OR word_rotl n y"
       
  4246   "word_rotr n (x OR y) = word_rotr n x OR word_rotr n y"
       
  4247   "word_rotl n (x XOR y) = word_rotl n x XOR word_rotl n y"
       
  4248   "word_rotr n (x XOR y) = word_rotr n x XOR word_rotr n y"  
       
  4249   by (rule word_bl.Rep_eqD,
       
  4250       rule word_rot_defs' [THEN trans],
       
  4251       simp only: blwl_syms [symmetric],
       
  4252       rule th1s [THEN trans], 
       
  4253       rule refl)+
       
  4254 end
       
  4255 
       
  4256 lemmas word_rot_logs = word_rotate.word_rot_logs
       
  4257 
       
  4258 lemmas bl_word_rotl_dt = trans [OF to_bl_rotl rotate_drop_take,
       
  4259   simplified word_bl.Rep', standard]
       
  4260 
       
  4261 lemmas bl_word_rotr_dt = trans [OF to_bl_rotr rotater_drop_take,
       
  4262   simplified word_bl.Rep', standard]
       
  4263 
       
  4264 lemma bl_word_roti_dt': 
       
  4265   "n = nat ((- i) mod int (size (w :: 'a :: len word))) ==> 
       
  4266     to_bl (word_roti i w) = drop n (to_bl w) @ take n (to_bl w)"
       
  4267   apply (unfold word_roti_def)
       
  4268   apply (simp add: bl_word_rotl_dt bl_word_rotr_dt word_size)
       
  4269   apply safe
       
  4270    apply (simp add: zmod_zminus1_eq_if)
       
  4271    apply safe
       
  4272     apply (simp add: nat_mult_distrib)
       
  4273    apply (simp add: nat_diff_distrib [OF pos_mod_sign pos_mod_conj 
       
  4274                                       [THEN conjunct2, THEN order_less_imp_le]]
       
  4275                     nat_mod_distrib)
       
  4276   apply (simp add: nat_mod_distrib)
       
  4277   done
       
  4278 
       
  4279 lemmas bl_word_roti_dt = bl_word_roti_dt' [unfolded word_size]
       
  4280 
       
  4281 lemmas word_rotl_dt = bl_word_rotl_dt 
       
  4282   [THEN word_bl.Rep_inverse' [symmetric], standard] 
       
  4283 lemmas word_rotr_dt = bl_word_rotr_dt 
       
  4284   [THEN word_bl.Rep_inverse' [symmetric], standard]
       
  4285 lemmas word_roti_dt = bl_word_roti_dt 
       
  4286   [THEN word_bl.Rep_inverse' [symmetric], standard]
       
  4287 
       
  4288 lemma word_rotx_0 [simp] : "word_rotr i 0 = 0 & word_rotl i 0 = 0"
       
  4289   by (simp add : word_rotr_dt word_rotl_dt to_bl_0 replicate_add [symmetric])
       
  4290 
       
  4291 lemma word_roti_0' [simp] : "word_roti n 0 = 0"
       
  4292   unfolding word_roti_def by auto
       
  4293 
       
  4294 lemmas word_rotr_dt_no_bin' [simp] = 
       
  4295   word_rotr_dt [where w="number_of w", unfolded to_bl_no_bin, standard]
       
  4296 
       
  4297 lemmas word_rotl_dt_no_bin' [simp] = 
       
  4298   word_rotl_dt [where w="number_of w", unfolded to_bl_no_bin, standard]
       
  4299 
       
  4300 declare word_roti_def [simp]
       
  4301 
       
  4302 
       
  4303 subsection {* Miscellaneous  *}
       
  4304 
       
  4305 declare of_nat_2p [simp]
       
  4306 
       
  4307 lemma word_int_cases:
       
  4308   "\<lbrakk>\<And>n. \<lbrakk>(x ::'a::len0 word) = word_of_int n; 0 \<le> n; n < 2^len_of TYPE('a)\<rbrakk> \<Longrightarrow> P\<rbrakk>
       
  4309    \<Longrightarrow> P"
       
  4310   by (cases x rule: word_uint.Abs_cases) (simp add: uints_num)
       
  4311 
       
  4312 lemma word_nat_cases [cases type: word]:
       
  4313   "\<lbrakk>\<And>n. \<lbrakk>(x ::'a::len word) = of_nat n; n < 2^len_of TYPE('a)\<rbrakk> \<Longrightarrow> P\<rbrakk>
       
  4314    \<Longrightarrow> P"
       
  4315   by (cases x rule: word_unat.Abs_cases) (simp add: unats_def)
       
  4316 
       
  4317 lemma max_word_eq:
       
  4318   "(max_word::'a::len word) = 2^len_of TYPE('a) - 1"
       
  4319   by (simp add: max_word_def word_of_int_hom_syms word_of_int_2p)
       
  4320 
       
  4321 lemma max_word_max [simp,intro!]:
       
  4322   "n \<le> max_word"
       
  4323   by (cases n rule: word_int_cases)
       
  4324      (simp add: max_word_def word_le_def int_word_uint int_mod_eq')
       
  4325   
       
  4326 lemma word_of_int_2p_len: 
       
  4327   "word_of_int (2 ^ len_of TYPE('a)) = (0::'a::len0 word)"
       
  4328   by (subst word_uint.Abs_norm [symmetric]) 
       
  4329      (simp add: word_of_int_hom_syms)
       
  4330 
       
  4331 lemma word_pow_0:
       
  4332   "(2::'a::len word) ^ len_of TYPE('a) = 0"
       
  4333 proof -
       
  4334   have "word_of_int (2 ^ len_of TYPE('a)) = (0::'a word)"
       
  4335     by (rule word_of_int_2p_len)
       
  4336   thus ?thesis by (simp add: word_of_int_2p)
       
  4337 qed
       
  4338 
       
  4339 lemma max_word_wrap: "x + 1 = 0 \<Longrightarrow> x = max_word"
       
  4340   apply (simp add: max_word_eq)
       
  4341   apply uint_arith
       
  4342   apply auto
       
  4343   apply (simp add: word_pow_0)
       
  4344   done
       
  4345 
       
  4346 lemma max_word_minus: 
       
  4347   "max_word = (-1::'a::len word)"
       
  4348 proof -
       
  4349   have "-1 + 1 = (0::'a word)" by simp
       
  4350   thus ?thesis by (rule max_word_wrap [symmetric])
       
  4351 qed
       
  4352 
       
  4353 lemma max_word_bl [simp]:
       
  4354   "to_bl (max_word::'a::len word) = replicate (len_of TYPE('a)) True"
       
  4355   by (subst max_word_minus to_bl_n1)+ simp
       
  4356 
       
  4357 lemma max_test_bit [simp]:
       
  4358   "(max_word::'a::len word) !! n = (n < len_of TYPE('a))"
       
  4359   by (auto simp add: test_bit_bl word_size)
       
  4360 
       
  4361 lemma word_and_max [simp]:
       
  4362   "x AND max_word = x"
       
  4363   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
       
  4364 
       
  4365 lemma word_or_max [simp]:
       
  4366   "x OR max_word = max_word"
       
  4367   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
       
  4368 
       
  4369 lemma word_ao_dist2:
       
  4370   "x AND (y OR z) = x AND y OR x AND (z::'a::len0 word)"
       
  4371   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
       
  4372 
       
  4373 lemma word_oa_dist2:
       
  4374   "x OR y AND z = (x OR y) AND (x OR (z::'a::len0 word))"
       
  4375   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
       
  4376 
       
  4377 lemma word_and_not [simp]:
       
  4378   "x AND NOT x = (0::'a::len0 word)"
       
  4379   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
       
  4380 
       
  4381 lemma word_or_not [simp]:
       
  4382   "x OR NOT x = max_word"
       
  4383   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
       
  4384 
       
  4385 lemma word_boolean:
       
  4386   "boolean (op AND) (op OR) bitNOT 0 max_word"
       
  4387   apply (rule boolean.intro)
       
  4388            apply (rule word_bw_assocs)
       
  4389           apply (rule word_bw_assocs)
       
  4390          apply (rule word_bw_comms)
       
  4391         apply (rule word_bw_comms)
       
  4392        apply (rule word_ao_dist2)
       
  4393       apply (rule word_oa_dist2)
       
  4394      apply (rule word_and_max)
       
  4395     apply (rule word_log_esimps)
       
  4396    apply (rule word_and_not)
       
  4397   apply (rule word_or_not)
       
  4398   done
       
  4399 
       
  4400 interpretation word_bool_alg:
       
  4401   boolean "op AND" "op OR" bitNOT 0 max_word
       
  4402   by (rule word_boolean)
       
  4403 
       
  4404 lemma word_xor_and_or:
       
  4405   "x XOR y = x AND NOT y OR NOT x AND (y::'a::len0 word)"
       
  4406   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
       
  4407 
       
  4408 interpretation word_bool_alg:
       
  4409   boolean_xor "op AND" "op OR" bitNOT 0 max_word "op XOR"
       
  4410   apply (rule boolean_xor.intro)
       
  4411    apply (rule word_boolean)
       
  4412   apply (rule boolean_xor_axioms.intro)
       
  4413   apply (rule word_xor_and_or)
       
  4414   done
       
  4415 
       
  4416 lemma shiftr_x_0 [iff]:
       
  4417   "(x::'a::len0 word) >> 0 = x"
       
  4418   by (simp add: shiftr_bl)
       
  4419 
       
  4420 lemma shiftl_x_0 [simp]: 
       
  4421   "(x :: 'a :: len word) << 0 = x"
       
  4422   by (simp add: shiftl_t2n)
       
  4423 
       
  4424 lemma shiftl_1 [simp]:
       
  4425   "(1::'a::len word) << n = 2^n"
       
  4426   by (simp add: shiftl_t2n)
       
  4427 
       
  4428 lemma uint_lt_0 [simp]:
       
  4429   "uint x < 0 = False"
       
  4430   by (simp add: linorder_not_less)
       
  4431 
       
  4432 lemma shiftr1_1 [simp]: 
       
  4433   "shiftr1 (1::'a::len word) = 0"
       
  4434   by (simp add: shiftr1_def word_0_alt)
       
  4435 
       
  4436 lemma shiftr_1[simp]: 
       
  4437   "(1::'a::len word) >> n = (if n = 0 then 1 else 0)"
       
  4438   by (induct n) (auto simp: shiftr_def)
       
  4439 
       
  4440 lemma word_less_1 [simp]: 
       
  4441   "((x::'a::len word) < 1) = (x = 0)"
       
  4442   by (simp add: word_less_nat_alt unat_0_iff)
       
  4443 
       
  4444 lemma to_bl_mask:
       
  4445   "to_bl (mask n :: 'a::len word) = 
       
  4446   replicate (len_of TYPE('a) - n) False @ 
       
  4447     replicate (min (len_of TYPE('a)) n) True"
       
  4448   by (simp add: mask_bl word_rep_drop min_def)
       
  4449 
       
  4450 lemma map_replicate_True:
       
  4451   "n = length xs ==>
       
  4452     map (\<lambda>(x,y). x & y) (zip xs (replicate n True)) = xs"
       
  4453   by (induct xs arbitrary: n) auto
       
  4454 
       
  4455 lemma map_replicate_False:
       
  4456   "n = length xs ==> map (\<lambda>(x,y). x & y)
       
  4457     (zip xs (replicate n False)) = replicate n False"
       
  4458   by (induct xs arbitrary: n) auto
       
  4459 
       
  4460 lemma bl_and_mask:
       
  4461   fixes w :: "'a::len word"
       
  4462   fixes n
       
  4463   defines "n' \<equiv> len_of TYPE('a) - n"
       
  4464   shows "to_bl (w AND mask n) =  replicate n' False @ drop n' (to_bl w)"
       
  4465 proof - 
       
  4466   note [simp] = map_replicate_True map_replicate_False
       
  4467   have "to_bl (w AND mask n) = 
       
  4468         map2 op & (to_bl w) (to_bl (mask n::'a::len word))"
       
  4469     by (simp add: bl_word_and)
       
  4470   also
       
  4471   have "to_bl w = take n' (to_bl w) @ drop n' (to_bl w)" by simp
       
  4472   also
       
  4473   have "map2 op & \<dots> (to_bl (mask n::'a::len word)) = 
       
  4474         replicate n' False @ drop n' (to_bl w)"
       
  4475     unfolding to_bl_mask n'_def map2_def
       
  4476     by (subst zip_append) auto
       
  4477   finally
       
  4478   show ?thesis .
       
  4479 qed
       
  4480 
       
  4481 lemma drop_rev_takefill:
       
  4482   "length xs \<le> n ==>
       
  4483     drop (n - length xs) (rev (takefill False n (rev xs))) = xs"
       
  4484   by (simp add: takefill_alt rev_take)
       
  4485 
       
  4486 lemma map_nth_0 [simp]:
       
  4487   "map (op !! (0::'a::len0 word)) xs = replicate (length xs) False"
       
  4488   by (induct xs) auto
       
  4489 
       
  4490 lemma uint_plus_if_size:
       
  4491   "uint (x + y) = 
       
  4492   (if uint x + uint y < 2^size x then 
       
  4493       uint x + uint y 
       
  4494    else 
       
  4495       uint x + uint y - 2^size x)" 
       
  4496   by (simp add: word_arith_alts int_word_uint mod_add_if_z 
       
  4497                 word_size)
       
  4498 
       
  4499 lemma unat_plus_if_size:
       
  4500   "unat (x + (y::'a::len word)) = 
       
  4501   (if unat x + unat y < 2^size x then 
       
  4502       unat x + unat y 
       
  4503    else 
       
  4504       unat x + unat y - 2^size x)" 
       
  4505   apply (subst word_arith_nat_defs)
       
  4506   apply (subst unat_of_nat)
       
  4507   apply (simp add:  mod_nat_add word_size)
       
  4508   done
       
  4509 
       
  4510 lemma word_neq_0_conv [simp]:
       
  4511   fixes w :: "'a :: len word"
       
  4512   shows "(w \<noteq> 0) = (0 < w)"
       
  4513 proof -
       
  4514   have "0 \<le> w" by (rule word_zero_le)
       
  4515   thus ?thesis by (auto simp add: word_less_def)
       
  4516 qed
       
  4517 
       
  4518 lemma max_lt:
       
  4519   "unat (max a b div c) = unat (max a b) div unat (c:: 'a :: len word)"
       
  4520   apply (subst word_arith_nat_defs)
       
  4521   apply (subst word_unat.eq_norm)
       
  4522   apply (subst mod_if)
       
  4523   apply clarsimp
       
  4524   apply (erule notE)
       
  4525   apply (insert div_le_dividend [of "unat (max a b)" "unat c"])
       
  4526   apply (erule order_le_less_trans)
       
  4527   apply (insert unat_lt2p [of "max a b"])
       
  4528   apply simp
       
  4529   done
       
  4530 
       
  4531 lemma uint_sub_if_size:
       
  4532   "uint (x - y) = 
       
  4533   (if uint y \<le> uint x then 
       
  4534       uint x - uint y 
       
  4535    else 
       
  4536       uint x - uint y + 2^size x)"
       
  4537   by (simp add: word_arith_alts int_word_uint mod_sub_if_z 
       
  4538                 word_size)
       
  4539 
       
  4540 lemma unat_sub:
       
  4541   "b <= a ==> unat (a - b) = unat a - unat b"
       
  4542   by (simp add: unat_def uint_sub_if_size word_le_def nat_diff_distrib)
       
  4543 
       
  4544 lemmas word_less_sub1_numberof [simp] =
       
  4545   word_less_sub1 [of "number_of w", standard]
       
  4546 lemmas word_le_sub1_numberof [simp] =
       
  4547   word_le_sub1 [of "number_of w", standard]
       
  4548   
       
  4549 lemma word_of_int_minus: 
       
  4550   "word_of_int (2^len_of TYPE('a) - i) = (word_of_int (-i)::'a::len word)"
       
  4551 proof -
       
  4552   have x: "2^len_of TYPE('a) - i = -i + 2^len_of TYPE('a)" by simp
       
  4553   show ?thesis
       
  4554     apply (subst x)
       
  4555     apply (subst word_uint.Abs_norm [symmetric], subst mod_add_self2)
       
  4556     apply simp
       
  4557     done
       
  4558 qed
       
  4559   
       
  4560 lemmas word_of_int_inj = 
       
  4561   word_uint.Abs_inject [unfolded uints_num, simplified]
       
  4562 
       
  4563 lemma word_le_less_eq:
       
  4564   "(x ::'z::len word) \<le> y = (x = y \<or> x < y)"
       
  4565   by (auto simp add: word_less_def)
       
  4566 
       
  4567 lemma mod_plus_cong:
       
  4568   assumes 1: "(b::int) = b'"
       
  4569       and 2: "x mod b' = x' mod b'"
       
  4570       and 3: "y mod b' = y' mod b'"
       
  4571       and 4: "x' + y' = z'"
       
  4572   shows "(x + y) mod b = z' mod b'"
       
  4573 proof -
       
  4574   from 1 2[symmetric] 3[symmetric] have "(x + y) mod b = (x' mod b' + y' mod b') mod b'"
       
  4575     by (simp add: mod_add_eq[symmetric])
       
  4576   also have "\<dots> = (x' + y') mod b'"
       
  4577     by (simp add: mod_add_eq[symmetric])
       
  4578   finally show ?thesis by (simp add: 4)
       
  4579 qed
       
  4580 
       
  4581 lemma mod_minus_cong:
       
  4582   assumes 1: "(b::int) = b'"
       
  4583       and 2: "x mod b' = x' mod b'"
       
  4584       and 3: "y mod b' = y' mod b'"
       
  4585       and 4: "x' - y' = z'"
       
  4586   shows "(x - y) mod b = z' mod b'"
       
  4587   using assms
       
  4588   apply (subst zmod_zsub_left_eq)
       
  4589   apply (subst zmod_zsub_right_eq)
       
  4590   apply (simp add: zmod_zsub_left_eq [symmetric] zmod_zsub_right_eq [symmetric])
       
  4591   done
       
  4592 
       
  4593 lemma word_induct_less: 
       
  4594   "\<lbrakk>P (0::'a::len word); \<And>n. \<lbrakk>n < m; P n\<rbrakk> \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P m"
       
  4595   apply (cases m)
       
  4596   apply atomize
       
  4597   apply (erule rev_mp)+
       
  4598   apply (rule_tac x=m in spec)
       
  4599   apply (induct_tac n)
       
  4600    apply simp
       
  4601   apply clarsimp
       
  4602   apply (erule impE)
       
  4603    apply clarsimp
       
  4604    apply (erule_tac x=n in allE)
       
  4605    apply (erule impE)
       
  4606     apply (simp add: unat_arith_simps)
       
  4607     apply (clarsimp simp: unat_of_nat)
       
  4608    apply simp
       
  4609   apply (erule_tac x="of_nat na" in allE)
       
  4610   apply (erule impE)
       
  4611    apply (simp add: unat_arith_simps)
       
  4612    apply (clarsimp simp: unat_of_nat)
       
  4613   apply simp
       
  4614   done
       
  4615   
       
  4616 lemma word_induct: 
       
  4617   "\<lbrakk>P (0::'a::len word); \<And>n. P n \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P m"
       
  4618   by (erule word_induct_less, simp)
       
  4619 
       
  4620 lemma word_induct2 [induct type]: 
       
  4621   "\<lbrakk>P 0; \<And>n. \<lbrakk>1 + n \<noteq> 0; P n\<rbrakk> \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P (n::'b::len word)"
       
  4622   apply (rule word_induct, simp)
       
  4623   apply (case_tac "1+n = 0", auto)
       
  4624   done
       
  4625 
       
  4626 definition word_rec :: "'a \<Rightarrow> ('b::len word \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'b word \<Rightarrow> 'a" where
       
  4627   "word_rec forZero forSuc n \<equiv> nat_rec forZero (forSuc \<circ> of_nat) (unat n)"
       
  4628 
       
  4629 lemma word_rec_0: "word_rec z s 0 = z"
       
  4630   by (simp add: word_rec_def)
       
  4631 
       
  4632 lemma word_rec_Suc: 
       
  4633   "1 + n \<noteq> (0::'a::len word) \<Longrightarrow> word_rec z s (1 + n) = s n (word_rec z s n)"
       
  4634   apply (simp add: word_rec_def unat_word_ariths)
       
  4635   apply (subst nat_mod_eq')
       
  4636    apply (cut_tac x=n in unat_lt2p)
       
  4637    apply (drule Suc_mono)
       
  4638    apply (simp add: less_Suc_eq_le)
       
  4639    apply (simp only: order_less_le, simp)
       
  4640    apply (erule contrapos_pn, simp)
       
  4641    apply (drule arg_cong[where f=of_nat])
       
  4642    apply simp
       
  4643    apply (subst (asm) word_unat.Rep_inverse[of n])
       
  4644    apply simp
       
  4645   apply simp
       
  4646   done
       
  4647 
       
  4648 lemma word_rec_Pred: 
       
  4649   "n \<noteq> 0 \<Longrightarrow> word_rec z s n = s (n - 1) (word_rec z s (n - 1))"
       
  4650   apply (rule subst[where t="n" and s="1 + (n - 1)"])
       
  4651    apply simp
       
  4652   apply (subst word_rec_Suc)
       
  4653    apply simp
       
  4654   apply simp
       
  4655   done
       
  4656 
       
  4657 lemma word_rec_in: 
       
  4658   "f (word_rec z (\<lambda>_. f) n) = word_rec (f z) (\<lambda>_. f) n"
       
  4659   by (induct n) (simp_all add: word_rec_0 word_rec_Suc)
       
  4660 
       
  4661 lemma word_rec_in2: 
       
  4662   "f n (word_rec z f n) = word_rec (f 0 z) (f \<circ> op + 1) n"
       
  4663   by (induct n) (simp_all add: word_rec_0 word_rec_Suc)
       
  4664 
       
  4665 lemma word_rec_twice: 
       
  4666   "m \<le> n \<Longrightarrow> word_rec z f n = word_rec (word_rec z f (n - m)) (f \<circ> op + (n - m)) m"
       
  4667 apply (erule rev_mp)
       
  4668 apply (rule_tac x=z in spec)
       
  4669 apply (rule_tac x=f in spec)
       
  4670 apply (induct n)
       
  4671  apply (simp add: word_rec_0)
       
  4672 apply clarsimp
       
  4673 apply (rule_tac t="1 + n - m" and s="1 + (n - m)" in subst)
       
  4674  apply simp
       
  4675 apply (case_tac "1 + (n - m) = 0")
       
  4676  apply (simp add: word_rec_0)
       
  4677  apply (rule_tac f = "word_rec ?a ?b" in arg_cong)
       
  4678  apply (rule_tac t="m" and s="m + (1 + (n - m))" in subst)
       
  4679   apply simp
       
  4680  apply (simp (no_asm_use))
       
  4681 apply (simp add: word_rec_Suc word_rec_in2)
       
  4682 apply (erule impE)
       
  4683  apply uint_arith
       
  4684 apply (drule_tac x="x \<circ> op + 1" in spec)
       
  4685 apply (drule_tac x="x 0 xa" in spec)
       
  4686 apply simp
       
  4687 apply (rule_tac t="\<lambda>a. x (1 + (n - m + a))" and s="\<lambda>a. x (1 + (n - m) + a)"
       
  4688        in subst)
       
  4689  apply (clarsimp simp add: expand_fun_eq)
       
  4690  apply (rule_tac t="(1 + (n - m + xb))" and s="1 + (n - m) + xb" in subst)
       
  4691   apply simp
       
  4692  apply (rule refl)
       
  4693 apply (rule refl)
       
  4694 done
       
  4695 
       
  4696 lemma word_rec_id: "word_rec z (\<lambda>_. id) n = z"
       
  4697   by (induct n) (auto simp add: word_rec_0 word_rec_Suc)
       
  4698 
       
  4699 lemma word_rec_id_eq: "\<forall>m < n. f m = id \<Longrightarrow> word_rec z f n = z"
       
  4700 apply (erule rev_mp)
       
  4701 apply (induct n)
       
  4702  apply (auto simp add: word_rec_0 word_rec_Suc)
       
  4703  apply (drule spec, erule mp)
       
  4704  apply uint_arith
       
  4705 apply (drule_tac x=n in spec, erule impE)
       
  4706  apply uint_arith
       
  4707 apply simp
       
  4708 done
       
  4709 
       
  4710 lemma word_rec_max: 
       
  4711   "\<forall>m\<ge>n. m \<noteq> -1 \<longrightarrow> f m = id \<Longrightarrow> word_rec z f -1 = word_rec z f n"
       
  4712 apply (subst word_rec_twice[where n="-1" and m="-1 - n"])
       
  4713  apply simp
       
  4714 apply simp
       
  4715 apply (rule word_rec_id_eq)
       
  4716 apply clarsimp
       
  4717 apply (drule spec, rule mp, erule mp)
       
  4718  apply (rule word_plus_mono_right2[OF _ order_less_imp_le])
       
  4719   prefer 2 
       
  4720   apply assumption
       
  4721  apply simp
       
  4722 apply (erule contrapos_pn)
       
  4723 apply simp
       
  4724 apply (drule arg_cong[where f="\<lambda>x. x - n"])
       
  4725 apply simp
       
  4726 done
       
  4727 
       
  4728 lemma unatSuc: 
       
  4729   "1 + n \<noteq> (0::'a::len word) \<Longrightarrow> unat (1 + n) = Suc (unat n)"
       
  4730   by unat_arith
       
  4731 
       
  4732 
       
  4733 lemmas word_no_1 [simp] = word_1_no [symmetric, unfolded BIT_simps]
       
  4734 lemmas word_no_0 [simp] = word_0_no [symmetric]
       
  4735 
       
  4736 declare word_0_bl [simp]
       
  4737 declare bin_to_bl_def [simp]
       
  4738 declare to_bl_0 [simp]
       
  4739 declare of_bl_True [simp]
       
  4740 
       
  4741 
       
  4742 use "~~/src/HOL/Tools/SMT/smt_word.ML"
       
  4743 
    12 setup {* SMT_Word.setup *}
  4744 setup {* SMT_Word.setup *}
    13 
  4745 
    14 text {* see @{text "Examples/WordExamples.thy"} for examples *}
       
    15 
       
    16 end
  4746 end