src/HOL/Word/Word.thy
changeset 70185 ac1706cdde25
parent 70183 3ea80c950023
child 70186 18e94864fd0f
equal deleted inserted replaced
70184:a7aba6db79a1 70185:ac1706cdde25
    16 
    16 
    17 text \<open>See \<^file>\<open>Word_Examples.thy\<close> for examples.\<close>
    17 text \<open>See \<^file>\<open>Word_Examples.thy\<close> for examples.\<close>
    18 
    18 
    19 subsection \<open>Type definition\<close>
    19 subsection \<open>Type definition\<close>
    20 
    20 
    21 typedef (overloaded) 'a word = "{(0::int) ..< 2 ^ len_of TYPE('a::len0)}"
    21 typedef (overloaded) 'a word = "{(0::int) ..< 2 ^ LENGTH('a::len0)}"
    22   morphisms uint Abs_word by auto
    22   morphisms uint Abs_word by auto
    23 
    23 
    24 lemma uint_nonnegative: "0 \<le> uint w"
    24 lemma uint_nonnegative: "0 \<le> uint w"
    25   using word.uint [of w] by simp
    25   using word.uint [of w] by simp
    26 
    26 
    27 lemma uint_bounded: "uint w < 2 ^ len_of TYPE('a)"
    27 lemma uint_bounded: "uint w < 2 ^ LENGTH('a)"
    28   for w :: "'a::len0 word"
    28   for w :: "'a::len0 word"
    29   using word.uint [of w] by simp
    29   using word.uint [of w] by simp
    30 
    30 
    31 lemma uint_idem: "uint w mod 2 ^ len_of TYPE('a) = uint w"
    31 lemma uint_idem: "uint w mod 2 ^ LENGTH('a) = uint w"
    32   for w :: "'a::len0 word"
    32   for w :: "'a::len0 word"
    33   using uint_nonnegative uint_bounded by (rule mod_pos_pos_trivial)
    33   using uint_nonnegative uint_bounded by (rule mod_pos_pos_trivial)
    34 
    34 
    35 lemma word_uint_eq_iff: "a = b \<longleftrightarrow> uint a = uint b"
    35 lemma word_uint_eq_iff: "a = b \<longleftrightarrow> uint a = uint b"
    36   by (simp add: uint_inject)
    36   by (simp add: uint_inject)
    39   by (simp add: word_uint_eq_iff)
    39   by (simp add: word_uint_eq_iff)
    40 
    40 
    41 definition word_of_int :: "int \<Rightarrow> 'a::len0 word"
    41 definition word_of_int :: "int \<Rightarrow> 'a::len0 word"
    42   \<comment> \<open>representation of words using unsigned or signed bins,
    42   \<comment> \<open>representation of words using unsigned or signed bins,
    43     only difference in these is the type class\<close>
    43     only difference in these is the type class\<close>
    44   where "word_of_int k = Abs_word (k mod 2 ^ len_of TYPE('a))"
    44   where "word_of_int k = Abs_word (k mod 2 ^ LENGTH('a))"
    45 
    45 
    46 lemma uint_word_of_int: "uint (word_of_int k :: 'a::len0 word) = k mod 2 ^ len_of TYPE('a)"
    46 lemma uint_word_of_int: "uint (word_of_int k :: 'a::len0 word) = k mod 2 ^ LENGTH('a)"
    47   by (auto simp add: word_of_int_def intro: Abs_word_inverse)
    47   by (auto simp add: word_of_int_def intro: Abs_word_inverse)
    48 
    48 
    49 lemma word_of_int_uint: "word_of_int (uint w) = w"
    49 lemma word_of_int_uint: "word_of_int (uint w) = w"
    50   by (simp add: word_of_int_def uint_idem uint_inverse)
    50   by (simp add: word_of_int_def uint_idem uint_inverse)
    51 
    51 
   109 lemmas lens_gt_0 = word_size_gt_0 len_gt_0
   109 lemmas lens_gt_0 = word_size_gt_0 len_gt_0
   110 
   110 
   111 lemma lens_not_0 [iff]:
   111 lemma lens_not_0 [iff]:
   112   fixes w :: "'a::len word"
   112   fixes w :: "'a::len word"
   113   shows "size w \<noteq> 0"
   113   shows "size w \<noteq> 0"
   114   and "len_of TYPE('a) \<noteq> 0"
   114   and "LENGTH('a) \<noteq> 0"
   115   by auto
   115   by auto
   116 
   116 
   117 definition source_size :: "('a::len0 word \<Rightarrow> 'b) \<Rightarrow> nat"
   117 definition source_size :: "('a::len0 word \<Rightarrow> 'b) \<Rightarrow> nat"
   118   \<comment> \<open>whether a cast (or other) function is to a longer or shorter length\<close>
   118   \<comment> \<open>whether a cast (or other) function is to a longer or shorter length\<close>
   119   where [code del]: "source_size c = (let arb = undefined; x = c arb in size arb)"
   119   where [code del]: "source_size c = (let arb = undefined; x = c arb in size arb)"
   129 
   129 
   130 definition of_bl :: "bool list \<Rightarrow> 'a::len0 word"
   130 definition of_bl :: "bool list \<Rightarrow> 'a::len0 word"
   131   where "of_bl bl = word_of_int (bl_to_bin bl)"
   131   where "of_bl bl = word_of_int (bl_to_bin bl)"
   132 
   132 
   133 definition to_bl :: "'a::len0 word \<Rightarrow> bool list"
   133 definition to_bl :: "'a::len0 word \<Rightarrow> bool list"
   134   where "to_bl w = bin_to_bl (len_of TYPE('a)) (uint w)"
   134   where "to_bl w = bin_to_bl (LENGTH('a)) (uint w)"
   135 
   135 
   136 definition word_reverse :: "'a::len0 word \<Rightarrow> 'a word"
   136 definition word_reverse :: "'a::len0 word \<Rightarrow> 'a word"
   137   where "word_reverse w = of_bl (rev (to_bl w))"
   137   where "word_reverse w = of_bl (rev (to_bl w))"
   138 
   138 
   139 definition word_int_case :: "(int \<Rightarrow> 'b) \<Rightarrow> 'a::len0 word \<Rightarrow> 'b"
   139 definition word_int_case :: "(int \<Rightarrow> 'b) \<Rightarrow> 'a::len0 word \<Rightarrow> 'b"
   148 
   148 
   149 definition cr_word :: "int \<Rightarrow> 'a::len0 word \<Rightarrow> bool"
   149 definition cr_word :: "int \<Rightarrow> 'a::len0 word \<Rightarrow> bool"
   150   where "cr_word = (\<lambda>x y. word_of_int x = y)"
   150   where "cr_word = (\<lambda>x y. word_of_int x = y)"
   151 
   151 
   152 lemma Quotient_word:
   152 lemma Quotient_word:
   153   "Quotient (\<lambda>x y. bintrunc (len_of TYPE('a)) x = bintrunc (len_of TYPE('a)) y)
   153   "Quotient (\<lambda>x y. bintrunc (LENGTH('a)) x = bintrunc (LENGTH('a)) y)
   154     word_of_int uint (cr_word :: _ \<Rightarrow> 'a::len0 word \<Rightarrow> bool)"
   154     word_of_int uint (cr_word :: _ \<Rightarrow> 'a::len0 word \<Rightarrow> bool)"
   155   unfolding Quotient_alt_def cr_word_def
   155   unfolding Quotient_alt_def cr_word_def
   156   by (simp add: no_bintr_alt1 word_of_int_uint) (simp add: word_of_int_def Abs_word_inject)
   156   by (simp add: no_bintr_alt1 word_of_int_uint) (simp add: word_of_int_def Abs_word_inject)
   157 
   157 
   158 lemma reflp_word:
   158 lemma reflp_word:
   159   "reflp (\<lambda>x y. bintrunc (len_of TYPE('a::len0)) x = bintrunc (len_of TYPE('a)) y)"
   159   "reflp (\<lambda>x y. bintrunc (LENGTH('a::len0)) x = bintrunc (LENGTH('a)) y)"
   160   by (simp add: reflp_def)
   160   by (simp add: reflp_def)
   161 
   161 
   162 setup_lifting Quotient_word reflp_word
   162 setup_lifting Quotient_word reflp_word
   163 
   163 
   164 text \<open>TODO: The next lemma could be generated automatically.\<close>
   164 text \<open>TODO: The next lemma could be generated automatically.\<close>
   165 
   165 
   166 lemma uint_transfer [transfer_rule]:
   166 lemma uint_transfer [transfer_rule]:
   167   "(rel_fun pcr_word (=)) (bintrunc (len_of TYPE('a))) (uint :: 'a::len0 word \<Rightarrow> int)"
   167   "(rel_fun pcr_word (=)) (bintrunc (LENGTH('a))) (uint :: 'a::len0 word \<Rightarrow> int)"
   168   unfolding rel_fun_def word.pcr_cr_eq cr_word_def
   168   unfolding rel_fun_def word.pcr_cr_eq cr_word_def
   169   by (simp add: no_bintr_alt1 uint_word_of_int)
   169   by (simp add: no_bintr_alt1 uint_word_of_int)
   170 
   170 
   171 
   171 
   172 subsection \<open>Basic code generation setup\<close>
   172 subsection \<open>Basic code generation setup\<close>
   214 lemmas uint_0 = uint_nonnegative (* FIXME duplicate *)
   214 lemmas uint_0 = uint_nonnegative (* FIXME duplicate *)
   215 lemmas uint_lt = uint_bounded (* FIXME duplicate *)
   215 lemmas uint_lt = uint_bounded (* FIXME duplicate *)
   216 lemmas uint_mod_same = uint_idem (* FIXME duplicate *)
   216 lemmas uint_mod_same = uint_idem (* FIXME duplicate *)
   217 
   217 
   218 lemma td_ext_uint:
   218 lemma td_ext_uint:
   219   "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (len_of TYPE('a::len0)))
   219   "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (LENGTH('a::len0)))
   220     (\<lambda>w::int. w mod 2 ^ len_of TYPE('a))"
   220     (\<lambda>w::int. w mod 2 ^ LENGTH('a))"
   221   apply (unfold td_ext_def')
   221   apply (unfold td_ext_def')
   222   apply (simp add: uints_num word_of_int_def bintrunc_mod2p)
   222   apply (simp add: uints_num word_of_int_def bintrunc_mod2p)
   223   apply (simp add: uint_mod_same uint_0 uint_lt
   223   apply (simp add: uint_mod_same uint_0 uint_lt
   224                    word.uint_inverse word.Abs_word_inverse int_mod_lem)
   224                    word.uint_inverse word.Abs_word_inverse int_mod_lem)
   225   done
   225   done
   226 
   226 
   227 interpretation word_uint:
   227 interpretation word_uint:
   228   td_ext
   228   td_ext
   229     "uint::'a::len0 word \<Rightarrow> int"
   229     "uint::'a::len0 word \<Rightarrow> int"
   230     word_of_int
   230     word_of_int
   231     "uints (len_of TYPE('a::len0))"
   231     "uints (LENGTH('a::len0))"
   232     "\<lambda>w. w mod 2 ^ len_of TYPE('a::len0)"
   232     "\<lambda>w. w mod 2 ^ LENGTH('a::len0)"
   233   by (fact td_ext_uint)
   233   by (fact td_ext_uint)
   234 
   234 
   235 lemmas td_uint = word_uint.td_thm
   235 lemmas td_uint = word_uint.td_thm
   236 lemmas int_word_uint = word_uint.eq_norm
   236 lemmas int_word_uint = word_uint.eq_norm
   237 
   237 
   238 lemma td_ext_ubin:
   238 lemma td_ext_ubin:
   239   "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (len_of TYPE('a::len0)))
   239   "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (LENGTH('a::len0)))
   240     (bintrunc (len_of TYPE('a)))"
   240     (bintrunc (LENGTH('a)))"
   241   by (unfold no_bintr_alt1) (fact td_ext_uint)
   241   by (unfold no_bintr_alt1) (fact td_ext_uint)
   242 
   242 
   243 interpretation word_ubin:
   243 interpretation word_ubin:
   244   td_ext
   244   td_ext
   245     "uint::'a::len0 word \<Rightarrow> int"
   245     "uint::'a::len0 word \<Rightarrow> int"
   246     word_of_int
   246     word_of_int
   247     "uints (len_of TYPE('a::len0))"
   247     "uints (LENGTH('a::len0))"
   248     "bintrunc (len_of TYPE('a::len0))"
   248     "bintrunc (LENGTH('a::len0))"
   249   by (fact td_ext_ubin)
   249   by (fact td_ext_ubin)
   250 
   250 
   251 
   251 
   252 subsection \<open>Arithmetic operations\<close>
   252 subsection \<open>Arithmetic operations\<close>
   253 
   253 
   315 
   315 
   316 lemmas word_of_int_hom_syms = word_of_int_homs [symmetric]
   316 lemmas word_of_int_hom_syms = word_of_int_homs [symmetric]
   317 
   317 
   318 instance word :: (len) comm_ring_1
   318 instance word :: (len) comm_ring_1
   319 proof
   319 proof
   320   have *: "0 < len_of TYPE('a)" by (rule len_gt_0)
   320   have *: "0 < LENGTH('a)" by (rule len_gt_0)
   321   show "(0::'a word) \<noteq> 1"
   321   show "(0::'a word) \<noteq> 1"
   322     by transfer (use * in \<open>auto simp add: gr0_conv_Suc\<close>)
   322     by transfer (use * in \<open>auto simp add: gr0_conv_Suc\<close>)
   323 qed
   323 qed
   324 
   324 
   325 lemma word_of_nat: "of_nat n = word_of_int (int n)"
   325 lemma word_of_nat: "of_nat n = word_of_int (int n)"
   429 
   429 
   430 definition mask :: "nat \<Rightarrow> 'a::len word"
   430 definition mask :: "nat \<Rightarrow> 'a::len word"
   431   where "mask n = (1 << n) - 1"
   431   where "mask n = (1 << n) - 1"
   432 
   432 
   433 definition revcast :: "'a::len0 word \<Rightarrow> 'b::len0 word"
   433 definition revcast :: "'a::len0 word \<Rightarrow> 'b::len0 word"
   434   where "revcast w =  of_bl (takefill False (len_of TYPE('b)) (to_bl w))"
   434   where "revcast w =  of_bl (takefill False (LENGTH('b)) (to_bl w))"
   435 
   435 
   436 definition slice1 :: "nat \<Rightarrow> 'a::len0 word \<Rightarrow> 'b::len0 word"
   436 definition slice1 :: "nat \<Rightarrow> 'a::len0 word \<Rightarrow> 'b::len0 word"
   437   where "slice1 n w = of_bl (takefill False n (to_bl w))"
   437   where "slice1 n w = of_bl (takefill False n (to_bl w))"
   438 
   438 
   439 definition slice :: "nat \<Rightarrow> 'a::len0 word \<Rightarrow> 'b::len0 word"
   439 definition slice :: "nat \<Rightarrow> 'a::len0 word \<Rightarrow> 'b::len0 word"
   461 
   461 
   462 
   462 
   463 subsection \<open>Split and cat operations\<close>
   463 subsection \<open>Split and cat operations\<close>
   464 
   464 
   465 definition word_cat :: "'a::len0 word \<Rightarrow> 'b::len0 word \<Rightarrow> 'c::len0 word"
   465 definition word_cat :: "'a::len0 word \<Rightarrow> 'b::len0 word \<Rightarrow> 'c::len0 word"
   466   where "word_cat a b = word_of_int (bin_cat (uint a) (len_of TYPE('b)) (uint b))"
   466   where "word_cat a b = word_of_int (bin_cat (uint a) (LENGTH('b)) (uint b))"
   467 
   467 
   468 definition word_split :: "'a::len0 word \<Rightarrow> 'b::len0 word \<times> 'c::len0 word"
   468 definition word_split :: "'a::len0 word \<Rightarrow> 'b::len0 word \<times> 'c::len0 word"
   469   where "word_split a =
   469   where "word_split a =
   470     (case bin_split (len_of TYPE('c)) (uint a) of
   470     (case bin_split (LENGTH('c)) (uint a) of
   471       (u, v) \<Rightarrow> (word_of_int u, word_of_int v))"
   471       (u, v) \<Rightarrow> (word_of_int u, word_of_int v))"
   472 
   472 
   473 definition word_rcat :: "'a::len0 word list \<Rightarrow> 'b::len0 word"
   473 definition word_rcat :: "'a::len0 word list \<Rightarrow> 'b::len0 word"
   474   where "word_rcat ws = word_of_int (bin_rcat (len_of TYPE('a)) (map uint ws))"
   474   where "word_rcat ws = word_of_int (bin_rcat (LENGTH('a)) (map uint ws))"
   475 
   475 
   476 definition word_rsplit :: "'a::len0 word \<Rightarrow> 'b::len word list"
   476 definition word_rsplit :: "'a::len0 word \<Rightarrow> 'b::len word list"
   477   where "word_rsplit w = map word_of_int (bin_rsplit (len_of TYPE('b)) (len_of TYPE('a), uint w))"
   477   where "word_rsplit w = map word_of_int (bin_rsplit (LENGTH('b)) (LENGTH('a), uint w))"
   478 
   478 
   479 definition max_word :: "'a::len word"
   479 definition max_word :: "'a::len word"
   480   \<comment> \<open>Largest representable machine integer.\<close>
   480   \<comment> \<open>Largest representable machine integer.\<close>
   481   where "max_word = word_of_int (2 ^ len_of TYPE('a) - 1)"
   481   where "max_word = word_of_int (2 ^ LENGTH('a) - 1)"
   482 
   482 
   483 lemmas of_nth_def = word_set_bits_def (* FIXME duplicate *)
   483 lemmas of_nth_def = word_set_bits_def (* FIXME duplicate *)
   484 
   484 
   485 
   485 
   486 subsection \<open>Theorems about typedefs\<close>
   486 subsection \<open>Theorems about typedefs\<close>
   487 
   487 
   488 lemma sint_sbintrunc': "sint (word_of_int bin :: 'a word) = sbintrunc (len_of TYPE('a::len) - 1) bin"
   488 lemma sint_sbintrunc': "sint (word_of_int bin :: 'a word) = sbintrunc (LENGTH('a::len) - 1) bin"
   489   by (auto simp: sint_uint word_ubin.eq_norm sbintrunc_bintrunc_lt)
   489   by (auto simp: sint_uint word_ubin.eq_norm sbintrunc_bintrunc_lt)
   490 
   490 
   491 lemma uint_sint: "uint w = bintrunc (len_of TYPE('a)) (sint w)"
   491 lemma uint_sint: "uint w = bintrunc (LENGTH('a)) (sint w)"
   492   for w :: "'a::len word"
   492   for w :: "'a::len word"
   493   by (auto simp: sint_uint bintrunc_sbintrunc_le)
   493   by (auto simp: sint_uint bintrunc_sbintrunc_le)
   494 
   494 
   495 lemma bintr_uint: "len_of TYPE('a) \<le> n \<Longrightarrow> bintrunc n (uint w) = uint w"
   495 lemma bintr_uint: "LENGTH('a) \<le> n \<Longrightarrow> bintrunc n (uint w) = uint w"
   496   for w :: "'a::len0 word"
   496   for w :: "'a::len0 word"
   497   apply (subst word_ubin.norm_Rep [symmetric])
   497   apply (subst word_ubin.norm_Rep [symmetric])
   498   apply (simp only: bintrunc_bintrunc_min word_size)
   498   apply (simp only: bintrunc_bintrunc_min word_size)
   499   apply (simp add: min.absorb2)
   499   apply (simp add: min.absorb2)
   500   done
   500   done
   501 
   501 
   502 lemma wi_bintr:
   502 lemma wi_bintr:
   503   "len_of TYPE('a::len0) \<le> n \<Longrightarrow>
   503   "LENGTH('a::len0) \<le> n \<Longrightarrow>
   504     word_of_int (bintrunc n w) = (word_of_int w :: 'a word)"
   504     word_of_int (bintrunc n w) = (word_of_int w :: 'a word)"
   505   by (auto simp: word_ubin.norm_eq_iff [symmetric] min.absorb1)
   505   by (auto simp: word_ubin.norm_eq_iff [symmetric] min.absorb1)
   506 
   506 
   507 lemma td_ext_sbin:
   507 lemma td_ext_sbin:
   508   "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (len_of TYPE('a::len)))
   508   "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (LENGTH('a::len)))
   509     (sbintrunc (len_of TYPE('a) - 1))"
   509     (sbintrunc (LENGTH('a) - 1))"
   510   apply (unfold td_ext_def' sint_uint)
   510   apply (unfold td_ext_def' sint_uint)
   511   apply (simp add : word_ubin.eq_norm)
   511   apply (simp add : word_ubin.eq_norm)
   512   apply (cases "len_of TYPE('a)")
   512   apply (cases "LENGTH('a)")
   513    apply (auto simp add : sints_def)
   513    apply (auto simp add : sints_def)
   514   apply (rule sym [THEN trans])
   514   apply (rule sym [THEN trans])
   515    apply (rule word_ubin.Abs_norm)
   515    apply (rule word_ubin.Abs_norm)
   516   apply (simp only: bintrunc_sbintrunc)
   516   apply (simp only: bintrunc_sbintrunc)
   517   apply (drule sym)
   517   apply (drule sym)
   518   apply simp
   518   apply simp
   519   done
   519   done
   520 
   520 
   521 lemma td_ext_sint:
   521 lemma td_ext_sint:
   522   "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (len_of TYPE('a::len)))
   522   "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (LENGTH('a::len)))
   523      (\<lambda>w. (w + 2 ^ (len_of TYPE('a) - 1)) mod 2 ^ len_of TYPE('a) -
   523      (\<lambda>w. (w + 2 ^ (LENGTH('a) - 1)) mod 2 ^ LENGTH('a) -
   524          2 ^ (len_of TYPE('a) - 1))"
   524          2 ^ (LENGTH('a) - 1))"
   525   using td_ext_sbin [where ?'a = 'a] by (simp add: no_sbintr_alt2)
   525   using td_ext_sbin [where ?'a = 'a] by (simp add: no_sbintr_alt2)
   526 
   526 
   527 text \<open>
   527 text \<open>
   528   We do \<open>sint\<close> before \<open>sbin\<close>, before \<open>sint\<close> is the user version
   528   We do \<open>sint\<close> before \<open>sbin\<close>, before \<open>sint\<close> is the user version
   529   and interpretations do not produce thm duplicates. I.e.
   529   and interpretations do not produce thm duplicates. I.e.
   532 \<close>
   532 \<close>
   533 interpretation word_sint:
   533 interpretation word_sint:
   534   td_ext
   534   td_ext
   535     "sint ::'a::len word \<Rightarrow> int"
   535     "sint ::'a::len word \<Rightarrow> int"
   536     word_of_int
   536     word_of_int
   537     "sints (len_of TYPE('a::len))"
   537     "sints (LENGTH('a::len))"
   538     "\<lambda>w. (w + 2^(len_of TYPE('a::len) - 1)) mod 2^len_of TYPE('a::len) -
   538     "\<lambda>w. (w + 2^(LENGTH('a::len) - 1)) mod 2^LENGTH('a::len) -
   539       2 ^ (len_of TYPE('a::len) - 1)"
   539       2 ^ (LENGTH('a::len) - 1)"
   540   by (rule td_ext_sint)
   540   by (rule td_ext_sint)
   541 
   541 
   542 interpretation word_sbin:
   542 interpretation word_sbin:
   543   td_ext
   543   td_ext
   544     "sint ::'a::len word \<Rightarrow> int"
   544     "sint ::'a::len word \<Rightarrow> int"
   545     word_of_int
   545     word_of_int
   546     "sints (len_of TYPE('a::len))"
   546     "sints (LENGTH('a::len))"
   547     "sbintrunc (len_of TYPE('a::len) - 1)"
   547     "sbintrunc (LENGTH('a::len) - 1)"
   548   by (rule td_ext_sbin)
   548   by (rule td_ext_sbin)
   549 
   549 
   550 lemmas int_word_sint = td_ext_sint [THEN td_ext.eq_norm]
   550 lemmas int_word_sint = td_ext_sint [THEN td_ext.eq_norm]
   551 
   551 
   552 lemmas td_sint = word_sint.td
   552 lemmas td_sint = word_sint.td
   553 
   553 
   554 lemma to_bl_def': "(to_bl :: 'a::len0 word \<Rightarrow> bool list) = bin_to_bl (len_of TYPE('a)) \<circ> uint"
   554 lemma to_bl_def': "(to_bl :: 'a::len0 word \<Rightarrow> bool list) = bin_to_bl (LENGTH('a)) \<circ> uint"
   555   by (auto simp: to_bl_def)
   555   by (auto simp: to_bl_def)
   556 
   556 
   557 lemmas word_reverse_no_def [simp] =
   557 lemmas word_reverse_no_def [simp] =
   558   word_reverse_def [of "numeral w"] for w
   558   word_reverse_def [of "numeral w"] for w
   559 
   559 
   576   apply (simp_all add: rel_fun_def word.pcr_cr_eq cr_word_def)
   576   apply (simp_all add: rel_fun_def word.pcr_cr_eq cr_word_def)
   577   using word_numeral_alt [symmetric] word_neg_numeral_alt [symmetric] by auto
   577   using word_numeral_alt [symmetric] word_neg_numeral_alt [symmetric] by auto
   578 
   578 
   579 lemma uint_bintrunc [simp]:
   579 lemma uint_bintrunc [simp]:
   580   "uint (numeral bin :: 'a word) =
   580   "uint (numeral bin :: 'a word) =
   581     bintrunc (len_of TYPE('a::len0)) (numeral bin)"
   581     bintrunc (LENGTH('a::len0)) (numeral bin)"
   582   unfolding word_numeral_alt by (rule word_ubin.eq_norm)
   582   unfolding word_numeral_alt by (rule word_ubin.eq_norm)
   583 
   583 
   584 lemma uint_bintrunc_neg [simp]:
   584 lemma uint_bintrunc_neg [simp]:
   585   "uint (- numeral bin :: 'a word) = bintrunc (len_of TYPE('a::len0)) (- numeral bin)"
   585   "uint (- numeral bin :: 'a word) = bintrunc (LENGTH('a::len0)) (- numeral bin)"
   586   by (simp only: word_neg_numeral_alt word_ubin.eq_norm)
   586   by (simp only: word_neg_numeral_alt word_ubin.eq_norm)
   587 
   587 
   588 lemma sint_sbintrunc [simp]:
   588 lemma sint_sbintrunc [simp]:
   589   "sint (numeral bin :: 'a word) = sbintrunc (len_of TYPE('a::len) - 1) (numeral bin)"
   589   "sint (numeral bin :: 'a word) = sbintrunc (LENGTH('a::len) - 1) (numeral bin)"
   590   by (simp only: word_numeral_alt word_sbin.eq_norm)
   590   by (simp only: word_numeral_alt word_sbin.eq_norm)
   591 
   591 
   592 lemma sint_sbintrunc_neg [simp]:
   592 lemma sint_sbintrunc_neg [simp]:
   593   "sint (- numeral bin :: 'a word) = sbintrunc (len_of TYPE('a::len) - 1) (- numeral bin)"
   593   "sint (- numeral bin :: 'a word) = sbintrunc (LENGTH('a::len) - 1) (- numeral bin)"
   594   by (simp only: word_neg_numeral_alt word_sbin.eq_norm)
   594   by (simp only: word_neg_numeral_alt word_sbin.eq_norm)
   595 
   595 
   596 lemma unat_bintrunc [simp]:
   596 lemma unat_bintrunc [simp]:
   597   "unat (numeral bin :: 'a::len0 word) = nat (bintrunc (len_of TYPE('a)) (numeral bin))"
   597   "unat (numeral bin :: 'a::len0 word) = nat (bintrunc (LENGTH('a)) (numeral bin))"
   598   by (simp only: unat_def uint_bintrunc)
   598   by (simp only: unat_def uint_bintrunc)
   599 
   599 
   600 lemma unat_bintrunc_neg [simp]:
   600 lemma unat_bintrunc_neg [simp]:
   601   "unat (- numeral bin :: 'a::len0 word) = nat (bintrunc (len_of TYPE('a)) (- numeral bin))"
   601   "unat (- numeral bin :: 'a::len0 word) = nat (bintrunc (LENGTH('a)) (- numeral bin))"
   602   by (simp only: unat_def uint_bintrunc_neg)
   602   by (simp only: unat_def uint_bintrunc_neg)
   603 
   603 
   604 lemma size_0_eq: "size w = 0 \<Longrightarrow> v = w"
   604 lemma size_0_eq: "size w = 0 \<Longrightarrow> v = w"
   605   for v w :: "'a::len0 word"
   605   for v w :: "'a::len0 word"
   606   apply (unfold word_size)
   606   apply (unfold word_size)
   613 
   613 
   614 lemma uint_ge_0 [iff]: "0 \<le> uint x"
   614 lemma uint_ge_0 [iff]: "0 \<le> uint x"
   615   for x :: "'a::len0 word"
   615   for x :: "'a::len0 word"
   616   using word_uint.Rep [of x] by (simp add: uints_num)
   616   using word_uint.Rep [of x] by (simp add: uints_num)
   617 
   617 
   618 lemma uint_lt2p [iff]: "uint x < 2 ^ len_of TYPE('a)"
   618 lemma uint_lt2p [iff]: "uint x < 2 ^ LENGTH('a)"
   619   for x :: "'a::len0 word"
   619   for x :: "'a::len0 word"
   620   using word_uint.Rep [of x] by (simp add: uints_num)
   620   using word_uint.Rep [of x] by (simp add: uints_num)
   621 
   621 
   622 lemma sint_ge: "- (2 ^ (len_of TYPE('a) - 1)) \<le> sint x"
   622 lemma sint_ge: "- (2 ^ (LENGTH('a) - 1)) \<le> sint x"
   623   for x :: "'a::len word"
   623   for x :: "'a::len word"
   624   using word_sint.Rep [of x] by (simp add: sints_num)
   624   using word_sint.Rep [of x] by (simp add: sints_num)
   625 
   625 
   626 lemma sint_lt: "sint x < 2 ^ (len_of TYPE('a) - 1)"
   626 lemma sint_lt: "sint x < 2 ^ (LENGTH('a) - 1)"
   627   for x :: "'a::len word"
   627   for x :: "'a::len word"
   628   using word_sint.Rep [of x] by (simp add: sints_num)
   628   using word_sint.Rep [of x] by (simp add: sints_num)
   629 
   629 
   630 lemma sign_uint_Pls [simp]: "bin_sign (uint x) = 0"
   630 lemma sign_uint_Pls [simp]: "bin_sign (uint x) = 0"
   631   by (simp add: sign_Pls_ge_0)
   631   by (simp add: sign_Pls_ge_0)
   632 
   632 
   633 lemma uint_m2p_neg: "uint x - 2 ^ len_of TYPE('a) < 0"
   633 lemma uint_m2p_neg: "uint x - 2 ^ LENGTH('a) < 0"
   634   for x :: "'a::len0 word"
   634   for x :: "'a::len0 word"
   635   by (simp only: diff_less_0_iff_less uint_lt2p)
   635   by (simp only: diff_less_0_iff_less uint_lt2p)
   636 
   636 
   637 lemma uint_m2p_not_non_neg: "\<not> 0 \<le> uint x - 2 ^ len_of TYPE('a)"
   637 lemma uint_m2p_not_non_neg: "\<not> 0 \<le> uint x - 2 ^ LENGTH('a)"
   638   for x :: "'a::len0 word"
   638   for x :: "'a::len0 word"
   639   by (simp only: not_le uint_m2p_neg)
   639   by (simp only: not_le uint_m2p_neg)
   640 
   640 
   641 lemma lt2p_lem: "len_of TYPE('a) \<le> n \<Longrightarrow> uint w < 2 ^ n"
   641 lemma lt2p_lem: "LENGTH('a) \<le> n \<Longrightarrow> uint w < 2 ^ n"
   642   for w :: "'a::len0 word"
   642   for w :: "'a::len0 word"
   643   by (metis bintr_uint bintrunc_mod2p int_mod_lem zless2p)
   643   by (metis bintr_uint bintrunc_mod2p int_mod_lem zless2p)
   644 
   644 
   645 lemma uint_le_0_iff [simp]: "uint x \<le> 0 \<longleftrightarrow> uint x = 0"
   645 lemma uint_le_0_iff [simp]: "uint x \<le> 0 \<longleftrightarrow> uint x = 0"
   646   by (fact uint_ge_0 [THEN leD, THEN linorder_antisym_conv1])
   646   by (fact uint_ge_0 [THEN leD, THEN linorder_antisym_conv1])
   647 
   647 
   648 lemma uint_nat: "uint w = int (unat w)"
   648 lemma uint_nat: "uint w = int (unat w)"
   649   by (auto simp: unat_def)
   649   by (auto simp: unat_def)
   650 
   650 
   651 lemma uint_numeral: "uint (numeral b :: 'a::len0 word) = numeral b mod 2 ^ len_of TYPE('a)"
   651 lemma uint_numeral: "uint (numeral b :: 'a::len0 word) = numeral b mod 2 ^ LENGTH('a)"
   652   by (simp only: word_numeral_alt int_word_uint)
   652   by (simp only: word_numeral_alt int_word_uint)
   653 
   653 
   654 lemma uint_neg_numeral: "uint (- numeral b :: 'a::len0 word) = - numeral b mod 2 ^ len_of TYPE('a)"
   654 lemma uint_neg_numeral: "uint (- numeral b :: 'a::len0 word) = - numeral b mod 2 ^ LENGTH('a)"
   655   by (simp only: word_neg_numeral_alt int_word_uint)
   655   by (simp only: word_neg_numeral_alt int_word_uint)
   656 
   656 
   657 lemma unat_numeral: "unat (numeral b :: 'a::len0 word) = numeral b mod 2 ^ len_of TYPE('a)"
   657 lemma unat_numeral: "unat (numeral b :: 'a::len0 word) = numeral b mod 2 ^ LENGTH('a)"
   658   apply (unfold unat_def)
   658   apply (unfold unat_def)
   659   apply (clarsimp simp only: uint_numeral)
   659   apply (clarsimp simp only: uint_numeral)
   660   apply (rule nat_mod_distrib [THEN trans])
   660   apply (rule nat_mod_distrib [THEN trans])
   661     apply (rule zero_le_numeral)
   661     apply (rule zero_le_numeral)
   662    apply (simp_all add: nat_power_eq)
   662    apply (simp_all add: nat_power_eq)
   663   done
   663   done
   664 
   664 
   665 lemma sint_numeral:
   665 lemma sint_numeral:
   666   "sint (numeral b :: 'a::len word) =
   666   "sint (numeral b :: 'a::len word) =
   667     (numeral b +
   667     (numeral b +
   668       2 ^ (len_of TYPE('a) - 1)) mod 2 ^ len_of TYPE('a) -
   668       2 ^ (LENGTH('a) - 1)) mod 2 ^ LENGTH('a) -
   669       2 ^ (len_of TYPE('a) - 1)"
   669       2 ^ (LENGTH('a) - 1)"
   670   unfolding word_numeral_alt by (rule int_word_sint)
   670   unfolding word_numeral_alt by (rule int_word_sint)
   671 
   671 
   672 lemma word_of_int_0 [simp, code_post]: "word_of_int 0 = 0"
   672 lemma word_of_int_0 [simp, code_post]: "word_of_int 0 = 0"
   673   unfolding word_0_wi ..
   673   unfolding word_0_wi ..
   674 
   674 
   684 lemma word_of_int_neg_numeral [simp]:
   684 lemma word_of_int_neg_numeral [simp]:
   685   "(word_of_int (- numeral bin) :: 'a::len0 word) = - numeral bin"
   685   "(word_of_int (- numeral bin) :: 'a::len0 word) = - numeral bin"
   686   by (simp only: word_numeral_alt wi_hom_syms)
   686   by (simp only: word_numeral_alt wi_hom_syms)
   687 
   687 
   688 lemma word_int_case_wi:
   688 lemma word_int_case_wi:
   689   "word_int_case f (word_of_int i :: 'b word) = f (i mod 2 ^ len_of TYPE('b::len0))"
   689   "word_int_case f (word_of_int i :: 'b word) = f (i mod 2 ^ LENGTH('b::len0))"
   690   by (simp add: word_int_case_def word_uint.eq_norm)
   690   by (simp add: word_int_case_def word_uint.eq_norm)
   691 
   691 
   692 lemma word_int_split:
   692 lemma word_int_split:
   693   "P (word_int_case f x) =
   693   "P (word_int_case f x) =
   694     (\<forall>i. x = (word_of_int i :: 'b::len0 word) \<and> 0 \<le> i \<and> i < 2 ^ len_of TYPE('b) \<longrightarrow> P (f i))"
   694     (\<forall>i. x = (word_of_int i :: 'b::len0 word) \<and> 0 \<le> i \<and> i < 2 ^ LENGTH('b) \<longrightarrow> P (f i))"
   695   by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial)
   695   by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial)
   696 
   696 
   697 lemma word_int_split_asm:
   697 lemma word_int_split_asm:
   698   "P (word_int_case f x) =
   698   "P (word_int_case f x) =
   699     (\<nexists>n. x = (word_of_int n :: 'b::len0 word) \<and> 0 \<le> n \<and> n < 2 ^ len_of TYPE('b::len0) \<and> \<not> P (f n))"
   699     (\<nexists>n. x = (word_of_int n :: 'b::len0 word) \<and> 0 \<le> n \<and> n < 2 ^ LENGTH('b::len0) \<and> \<not> P (f n))"
   700   by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial)
   700   by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial)
   701 
   701 
   702 lemmas uint_range' = word_uint.Rep [unfolded uints_num mem_Collect_eq]
   702 lemmas uint_range' = word_uint.Rep [unfolded uints_num mem_Collect_eq]
   703 lemmas sint_range' = word_sint.Rep [unfolded One_nat_def sints_num mem_Collect_eq]
   703 lemmas sint_range' = word_sint.Rep [unfolded One_nat_def sints_num mem_Collect_eq]
   704 
   704 
   729   apply (subst word_ubin.norm_Rep [symmetric])
   729   apply (subst word_ubin.norm_Rep [symmetric])
   730   apply (simp only: nth_bintr word_size)
   730   apply (simp only: nth_bintr word_size)
   731   apply fast
   731   apply fast
   732   done
   732   done
   733 
   733 
   734 lemma word_eq_iff: "x = y \<longleftrightarrow> (\<forall>n<len_of TYPE('a). x !! n = y !! n)"
   734 lemma word_eq_iff: "x = y \<longleftrightarrow> (\<forall>n<LENGTH('a). x !! n = y !! n)"
   735   for x y :: "'a::len0 word"
   735   for x y :: "'a::len0 word"
   736   unfolding uint_inject [symmetric] bin_eq_iff word_test_bit_def [symmetric]
   736   unfolding uint_inject [symmetric] bin_eq_iff word_test_bit_def [symmetric]
   737   by (metis test_bit_size [unfolded word_size])
   737   by (metis test_bit_size [unfolded word_size])
   738 
   738 
   739 lemma word_eqI: "(\<And>n. n < size u \<longrightarrow> u !! n = v !! n) \<Longrightarrow> u = v"
   739 lemma word_eqI: "(\<And>n. n < size u \<longrightarrow> u !! n = v !! n) \<Longrightarrow> u = v"
   747 lemma test_bit_bin': "w !! n \<longleftrightarrow> n < size w \<and> bin_nth (uint w) n"
   747 lemma test_bit_bin': "w !! n \<longleftrightarrow> n < size w \<and> bin_nth (uint w) n"
   748   by (simp add: word_test_bit_def word_size nth_bintr [symmetric])
   748   by (simp add: word_test_bit_def word_size nth_bintr [symmetric])
   749 
   749 
   750 lemmas test_bit_bin = test_bit_bin' [unfolded word_size]
   750 lemmas test_bit_bin = test_bit_bin' [unfolded word_size]
   751 
   751 
   752 lemma bin_nth_uint_imp: "bin_nth (uint w) n \<Longrightarrow> n < len_of TYPE('a)"
   752 lemma bin_nth_uint_imp: "bin_nth (uint w) n \<Longrightarrow> n < LENGTH('a)"
   753   for w :: "'a::len0 word"
   753   for w :: "'a::len0 word"
   754   apply (rule nth_bintr [THEN iffD1, THEN conjunct1])
   754   apply (rule nth_bintr [THEN iffD1, THEN conjunct1])
   755   apply (subst word_ubin.norm_Rep)
   755   apply (subst word_ubin.norm_Rep)
   756   apply assumption
   756   apply assumption
   757   done
   757   done
   758 
   758 
   759 lemma bin_nth_sint:
   759 lemma bin_nth_sint:
   760   "len_of TYPE('a) \<le> n \<Longrightarrow>
   760   "LENGTH('a) \<le> n \<Longrightarrow>
   761     bin_nth (sint w) n = bin_nth (sint w) (len_of TYPE('a) - 1)"
   761     bin_nth (sint w) n = bin_nth (sint w) (LENGTH('a) - 1)"
   762   for w :: "'a::len word"
   762   for w :: "'a::len word"
   763   apply (subst word_sbin.norm_Rep [symmetric])
   763   apply (subst word_sbin.norm_Rep [symmetric])
   764   apply (auto simp add: nth_sbintr)
   764   apply (auto simp add: nth_sbintr)
   765   done
   765   done
   766 
   766 
   767 \<comment> \<open>type definitions theorem for in terms of equivalent bool list\<close>
   767 \<comment> \<open>type definitions theorem for in terms of equivalent bool list\<close>
   768 lemma td_bl:
   768 lemma td_bl:
   769   "type_definition
   769   "type_definition
   770     (to_bl :: 'a::len0 word \<Rightarrow> bool list)
   770     (to_bl :: 'a::len0 word \<Rightarrow> bool list)
   771     of_bl
   771     of_bl
   772     {bl. length bl = len_of TYPE('a)}"
   772     {bl. length bl = LENGTH('a)}"
   773   apply (unfold type_definition_def of_bl_def to_bl_def)
   773   apply (unfold type_definition_def of_bl_def to_bl_def)
   774   apply (simp add: word_ubin.eq_norm)
   774   apply (simp add: word_ubin.eq_norm)
   775   apply safe
   775   apply safe
   776   apply (drule sym)
   776   apply (drule sym)
   777   apply simp
   777   apply simp
   779 
   779 
   780 interpretation word_bl:
   780 interpretation word_bl:
   781   type_definition
   781   type_definition
   782     "to_bl :: 'a::len0 word \<Rightarrow> bool list"
   782     "to_bl :: 'a::len0 word \<Rightarrow> bool list"
   783     of_bl
   783     of_bl
   784     "{bl. length bl = len_of TYPE('a::len0)}"
   784     "{bl. length bl = LENGTH('a::len0)}"
   785   by (fact td_bl)
   785   by (fact td_bl)
   786 
   786 
   787 lemmas word_bl_Rep' = word_bl.Rep [unfolded mem_Collect_eq, iff]
   787 lemmas word_bl_Rep' = word_bl.Rep [unfolded mem_Collect_eq, iff]
   788 
   788 
   789 lemma word_size_bl: "size w = size (to_bl w)"
   789 lemma word_size_bl: "size w = size (to_bl w)"
   821   apply (rule trans [OF _ bl_sbin_sign])
   821   apply (rule trans [OF _ bl_sbin_sign])
   822   apply simp
   822   apply simp
   823   done
   823   done
   824 
   824 
   825 lemma of_bl_drop':
   825 lemma of_bl_drop':
   826   "lend = length bl - len_of TYPE('a::len0) \<Longrightarrow>
   826   "lend = length bl - LENGTH('a::len0) \<Longrightarrow>
   827     of_bl (drop lend bl) = (of_bl bl :: 'a word)"
   827     of_bl (drop lend bl) = (of_bl bl :: 'a word)"
   828   by (auto simp: of_bl_def trunc_bl2bin [symmetric])
   828   by (auto simp: of_bl_def trunc_bl2bin [symmetric])
   829 
   829 
   830 lemma test_bit_of_bl:
   830 lemma test_bit_of_bl:
   831   "(of_bl bl::'a::len0 word) !! n = (rev bl ! n \<and> n < len_of TYPE('a) \<and> n < length bl)"
   831   "(of_bl bl::'a::len0 word) !! n = (rev bl ! n \<and> n < LENGTH('a) \<and> n < length bl)"
   832   by (auto simp add: of_bl_def word_test_bit_def word_size
   832   by (auto simp add: of_bl_def word_test_bit_def word_size
   833       word_ubin.eq_norm nth_bintr bin_nth_of_bl)
   833       word_ubin.eq_norm nth_bintr bin_nth_of_bl)
   834 
   834 
   835 lemma no_of_bl: "(numeral bin ::'a::len0 word) = of_bl (bin_to_bl (len_of TYPE('a)) (numeral bin))"
   835 lemma no_of_bl: "(numeral bin ::'a::len0 word) = of_bl (bin_to_bl (LENGTH('a)) (numeral bin))"
   836   by (simp add: of_bl_def)
   836   by (simp add: of_bl_def)
   837 
   837 
   838 lemma uint_bl: "to_bl w = bin_to_bl (size w) (uint w)"
   838 lemma uint_bl: "to_bl w = bin_to_bl (size w) (uint w)"
   839   by (auto simp: word_size to_bl_def)
   839   by (auto simp: word_size to_bl_def)
   840 
   840 
   841 lemma to_bl_bin: "bl_to_bin (to_bl w) = uint w"
   841 lemma to_bl_bin: "bl_to_bin (to_bl w) = uint w"
   842   by (simp add: uint_bl word_size)
   842   by (simp add: uint_bl word_size)
   843 
   843 
   844 lemma to_bl_of_bin: "to_bl (word_of_int bin::'a::len0 word) = bin_to_bl (len_of TYPE('a)) bin"
   844 lemma to_bl_of_bin: "to_bl (word_of_int bin::'a::len0 word) = bin_to_bl (LENGTH('a)) bin"
   845   by (auto simp: uint_bl word_ubin.eq_norm word_size)
   845   by (auto simp: uint_bl word_ubin.eq_norm word_size)
   846 
   846 
   847 lemma to_bl_numeral [simp]:
   847 lemma to_bl_numeral [simp]:
   848   "to_bl (numeral bin::'a::len0 word) =
   848   "to_bl (numeral bin::'a::len0 word) =
   849     bin_to_bl (len_of TYPE('a)) (numeral bin)"
   849     bin_to_bl (LENGTH('a)) (numeral bin)"
   850   unfolding word_numeral_alt by (rule to_bl_of_bin)
   850   unfolding word_numeral_alt by (rule to_bl_of_bin)
   851 
   851 
   852 lemma to_bl_neg_numeral [simp]:
   852 lemma to_bl_neg_numeral [simp]:
   853   "to_bl (- numeral bin::'a::len0 word) =
   853   "to_bl (- numeral bin::'a::len0 word) =
   854     bin_to_bl (len_of TYPE('a)) (- numeral bin)"
   854     bin_to_bl (LENGTH('a)) (- numeral bin)"
   855   unfolding word_neg_numeral_alt by (rule to_bl_of_bin)
   855   unfolding word_neg_numeral_alt by (rule to_bl_of_bin)
   856 
   856 
   857 lemma to_bl_to_bin [simp] : "bl_to_bin (to_bl w) = uint w"
   857 lemma to_bl_to_bin [simp] : "bl_to_bin (to_bl w) = uint w"
   858   by (simp add: uint_bl word_size)
   858   by (simp add: uint_bl word_size)
   859 
   859 
   860 lemma uint_bl_bin: "bl_to_bin (bin_to_bl (len_of TYPE('a)) (uint x)) = uint x"
   860 lemma uint_bl_bin: "bl_to_bin (bin_to_bl (LENGTH('a)) (uint x)) = uint x"
   861   for x :: "'a::len0 word"
   861   for x :: "'a::len0 word"
   862   by (rule trans [OF bin_bl_bin word_ubin.norm_Rep])
   862   by (rule trans [OF bin_bl_bin word_ubin.norm_Rep])
   863 
   863 
   864 \<comment> \<open>naturals\<close>
   864 \<comment> \<open>naturals\<close>
   865 lemma uints_unats: "uints n = int ` unats n"
   865 lemma uints_unats: "uints n = int ` unats n"
   876   word_ubin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b
   876   word_ubin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b
   877 lemmas sbintr_num =
   877 lemmas sbintr_num =
   878   word_sbin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b
   878   word_sbin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b
   879 
   879 
   880 lemma num_of_bintr':
   880 lemma num_of_bintr':
   881   "bintrunc (len_of TYPE('a::len0)) (numeral a) = (numeral b) \<Longrightarrow>
   881   "bintrunc (LENGTH('a::len0)) (numeral a) = (numeral b) \<Longrightarrow>
   882     numeral a = (numeral b :: 'a word)"
   882     numeral a = (numeral b :: 'a word)"
   883   unfolding bintr_num by (erule subst, simp)
   883   unfolding bintr_num by (erule subst, simp)
   884 
   884 
   885 lemma num_of_sbintr':
   885 lemma num_of_sbintr':
   886   "sbintrunc (len_of TYPE('a::len) - 1) (numeral a) = (numeral b) \<Longrightarrow>
   886   "sbintrunc (LENGTH('a::len) - 1) (numeral a) = (numeral b) \<Longrightarrow>
   887     numeral a = (numeral b :: 'a word)"
   887     numeral a = (numeral b :: 'a word)"
   888   unfolding sbintr_num by (erule subst, simp)
   888   unfolding sbintr_num by (erule subst, simp)
   889 
   889 
   890 lemma num_abs_bintr:
   890 lemma num_abs_bintr:
   891   "(numeral x :: 'a word) =
   891   "(numeral x :: 'a word) =
   892     word_of_int (bintrunc (len_of TYPE('a::len0)) (numeral x))"
   892     word_of_int (bintrunc (LENGTH('a::len0)) (numeral x))"
   893   by (simp only: word_ubin.Abs_norm word_numeral_alt)
   893   by (simp only: word_ubin.Abs_norm word_numeral_alt)
   894 
   894 
   895 lemma num_abs_sbintr:
   895 lemma num_abs_sbintr:
   896   "(numeral x :: 'a word) =
   896   "(numeral x :: 'a word) =
   897     word_of_int (sbintrunc (len_of TYPE('a::len) - 1) (numeral x))"
   897     word_of_int (sbintrunc (LENGTH('a::len) - 1) (numeral x))"
   898   by (simp only: word_sbin.Abs_norm word_numeral_alt)
   898   by (simp only: word_sbin.Abs_norm word_numeral_alt)
   899 
   899 
   900 text \<open>
   900 text \<open>
   901   \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result,
   901   \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result,
   902   thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>!
   902   thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>!
   909   by (auto simp: scast_def)
   909   by (auto simp: scast_def)
   910 
   910 
   911 lemma ucast_bl: "ucast w = of_bl (to_bl w)"
   911 lemma ucast_bl: "ucast w = of_bl (to_bl w)"
   912   by (auto simp: ucast_def of_bl_def uint_bl word_size)
   912   by (auto simp: ucast_def of_bl_def uint_bl word_size)
   913 
   913 
   914 lemma nth_ucast: "(ucast w::'a::len0 word) !! n = (w !! n \<and> n < len_of TYPE('a))"
   914 lemma nth_ucast: "(ucast w::'a::len0 word) !! n = (w !! n \<and> n < LENGTH('a))"
   915   by (simp add: ucast_def test_bit_bin word_ubin.eq_norm nth_bintr word_size)
   915   by (simp add: ucast_def test_bit_bin word_ubin.eq_norm nth_bintr word_size)
   916     (fast elim!: bin_nth_uint_imp)
   916     (fast elim!: bin_nth_uint_imp)
   917 
   917 
   918 \<comment> \<open>literal u(s)cast\<close>
   918 \<comment> \<open>literal u(s)cast\<close>
   919 lemma ucast_bintr [simp]:
   919 lemma ucast_bintr [simp]:
   920   "ucast (numeral w :: 'a::len0 word) =
   920   "ucast (numeral w :: 'a::len0 word) =
   921     word_of_int (bintrunc (len_of TYPE('a)) (numeral w))"
   921     word_of_int (bintrunc (LENGTH('a)) (numeral w))"
   922   by (simp add: ucast_def)
   922   by (simp add: ucast_def)
   923 
   923 
   924 (* TODO: neg_numeral *)
   924 (* TODO: neg_numeral *)
   925 
   925 
   926 lemma scast_sbintr [simp]:
   926 lemma scast_sbintr [simp]:
   927   "scast (numeral w ::'a::len word) =
   927   "scast (numeral w ::'a::len word) =
   928     word_of_int (sbintrunc (len_of TYPE('a) - Suc 0) (numeral w))"
   928     word_of_int (sbintrunc (LENGTH('a) - Suc 0) (numeral w))"
   929   by (simp add: scast_def)
   929   by (simp add: scast_def)
   930 
   930 
   931 lemma source_size: "source_size (c::'a::len0 word \<Rightarrow> _) = len_of TYPE('a)"
   931 lemma source_size: "source_size (c::'a::len0 word \<Rightarrow> _) = LENGTH('a)"
   932   unfolding source_size_def word_size Let_def ..
   932   unfolding source_size_def word_size Let_def ..
   933 
   933 
   934 lemma target_size: "target_size (c::_ \<Rightarrow> 'b::len0 word) = len_of TYPE('b)"
   934 lemma target_size: "target_size (c::_ \<Rightarrow> 'b::len0 word) = LENGTH('b)"
   935   unfolding target_size_def word_size Let_def ..
   935   unfolding target_size_def word_size Let_def ..
   936 
   936 
   937 lemma is_down: "is_down c \<longleftrightarrow> len_of TYPE('b) \<le> len_of TYPE('a)"
   937 lemma is_down: "is_down c \<longleftrightarrow> LENGTH('b) \<le> LENGTH('a)"
   938   for c :: "'a::len0 word \<Rightarrow> 'b::len0 word"
   938   for c :: "'a::len0 word \<Rightarrow> 'b::len0 word"
   939   by (simp only: is_down_def source_size target_size)
   939   by (simp only: is_down_def source_size target_size)
   940 
   940 
   941 lemma is_up: "is_up c \<longleftrightarrow> len_of TYPE('a) \<le> len_of TYPE('b)"
   941 lemma is_up: "is_up c \<longleftrightarrow> LENGTH('a) \<le> LENGTH('b)"
   942   for c :: "'a::len0 word \<Rightarrow> 'b::len0 word"
   942   for c :: "'a::len0 word \<Rightarrow> 'b::len0 word"
   943   by (simp only: is_up_def source_size target_size)
   943   by (simp only: is_up_def source_size target_size)
   944 
   944 
   945 lemmas is_up_down = trans [OF is_up is_down [symmetric]]
   945 lemmas is_up_down = trans [OF is_up is_down [symmetric]]
   946 
   946 
   953   apply simp
   953   apply simp
   954   done
   954   done
   955 
   955 
   956 lemma word_rev_tf:
   956 lemma word_rev_tf:
   957   "to_bl (of_bl bl::'a::len0 word) =
   957   "to_bl (of_bl bl::'a::len0 word) =
   958     rev (takefill False (len_of TYPE('a)) (rev bl))"
   958     rev (takefill False (LENGTH('a)) (rev bl))"
   959   by (auto simp: of_bl_def uint_bl bl_bin_bl_rtf word_ubin.eq_norm word_size)
   959   by (auto simp: of_bl_def uint_bl bl_bin_bl_rtf word_ubin.eq_norm word_size)
   960 
   960 
   961 lemma word_rep_drop:
   961 lemma word_rep_drop:
   962   "to_bl (of_bl bl::'a::len0 word) =
   962   "to_bl (of_bl bl::'a::len0 word) =
   963     replicate (len_of TYPE('a) - length bl) False @
   963     replicate (LENGTH('a) - length bl) False @
   964     drop (length bl - len_of TYPE('a)) bl"
   964     drop (length bl - LENGTH('a)) bl"
   965   by (simp add: word_rev_tf takefill_alt rev_take)
   965   by (simp add: word_rev_tf takefill_alt rev_take)
   966 
   966 
   967 lemma to_bl_ucast:
   967 lemma to_bl_ucast:
   968   "to_bl (ucast (w::'b::len0 word) ::'a::len0 word) =
   968   "to_bl (ucast (w::'b::len0 word) ::'a::len0 word) =
   969     replicate (len_of TYPE('a) - len_of TYPE('b)) False @
   969     replicate (LENGTH('a) - LENGTH('b)) False @
   970     drop (len_of TYPE('b) - len_of TYPE('a)) (to_bl w)"
   970     drop (LENGTH('b) - LENGTH('a)) (to_bl w)"
   971   apply (unfold ucast_bl)
   971   apply (unfold ucast_bl)
   972   apply (rule trans)
   972   apply (rule trans)
   973    apply (rule word_rep_drop)
   973    apply (rule word_rep_drop)
   974   apply simp
   974   apply simp
   975   done
   975   done
  1115   unfolding word_0_wi word_ubin.eq_norm by simp
  1115   unfolding word_0_wi word_ubin.eq_norm by simp
  1116 
  1116 
  1117 lemma of_bl_0 [simp]: "of_bl (replicate n False) = 0"
  1117 lemma of_bl_0 [simp]: "of_bl (replicate n False) = 0"
  1118   by (simp add: of_bl_def bl_to_bin_rep_False)
  1118   by (simp add: of_bl_def bl_to_bin_rep_False)
  1119 
  1119 
  1120 lemma to_bl_0 [simp]: "to_bl (0::'a::len0 word) = replicate (len_of TYPE('a)) False"
  1120 lemma to_bl_0 [simp]: "to_bl (0::'a::len0 word) = replicate (LENGTH('a)) False"
  1121   by (simp add: uint_bl word_size bin_to_bl_zero)
  1121   by (simp add: uint_bl word_size bin_to_bl_zero)
  1122 
  1122 
  1123 lemma uint_0_iff: "uint x = 0 \<longleftrightarrow> x = 0"
  1123 lemma uint_0_iff: "uint x = 0 \<longleftrightarrow> x = 0"
  1124   by (simp add: word_uint_eq_iff)
  1124   by (simp add: word_uint_eq_iff)
  1125 
  1125 
  1187 lemma uint_cong: "x = y \<Longrightarrow> uint x = uint y"
  1187 lemma uint_cong: "x = y \<Longrightarrow> uint x = uint y"
  1188   by simp
  1188   by simp
  1189 
  1189 
  1190 lemma uint_word_ariths:
  1190 lemma uint_word_ariths:
  1191   fixes a b :: "'a::len0 word"
  1191   fixes a b :: "'a::len0 word"
  1192   shows "uint (a + b) = (uint a + uint b) mod 2 ^ len_of TYPE('a::len0)"
  1192   shows "uint (a + b) = (uint a + uint b) mod 2 ^ LENGTH('a::len0)"
  1193     and "uint (a - b) = (uint a - uint b) mod 2 ^ len_of TYPE('a)"
  1193     and "uint (a - b) = (uint a - uint b) mod 2 ^ LENGTH('a)"
  1194     and "uint (a * b) = uint a * uint b mod 2 ^ len_of TYPE('a)"
  1194     and "uint (a * b) = uint a * uint b mod 2 ^ LENGTH('a)"
  1195     and "uint (- a) = - uint a mod 2 ^ len_of TYPE('a)"
  1195     and "uint (- a) = - uint a mod 2 ^ LENGTH('a)"
  1196     and "uint (word_succ a) = (uint a + 1) mod 2 ^ len_of TYPE('a)"
  1196     and "uint (word_succ a) = (uint a + 1) mod 2 ^ LENGTH('a)"
  1197     and "uint (word_pred a) = (uint a - 1) mod 2 ^ len_of TYPE('a)"
  1197     and "uint (word_pred a) = (uint a - 1) mod 2 ^ LENGTH('a)"
  1198     and "uint (0 :: 'a word) = 0 mod 2 ^ len_of TYPE('a)"
  1198     and "uint (0 :: 'a word) = 0 mod 2 ^ LENGTH('a)"
  1199     and "uint (1 :: 'a word) = 1 mod 2 ^ len_of TYPE('a)"
  1199     and "uint (1 :: 'a word) = 1 mod 2 ^ LENGTH('a)"
  1200   by (simp_all add: word_arith_wis [THEN trans [OF uint_cong int_word_uint]])
  1200   by (simp_all add: word_arith_wis [THEN trans [OF uint_cong int_word_uint]])
  1201 
  1201 
  1202 lemma uint_word_arith_bintrs:
  1202 lemma uint_word_arith_bintrs:
  1203   fixes a b :: "'a::len0 word"
  1203   fixes a b :: "'a::len0 word"
  1204   shows "uint (a + b) = bintrunc (len_of TYPE('a)) (uint a + uint b)"
  1204   shows "uint (a + b) = bintrunc (LENGTH('a)) (uint a + uint b)"
  1205     and "uint (a - b) = bintrunc (len_of TYPE('a)) (uint a - uint b)"
  1205     and "uint (a - b) = bintrunc (LENGTH('a)) (uint a - uint b)"
  1206     and "uint (a * b) = bintrunc (len_of TYPE('a)) (uint a * uint b)"
  1206     and "uint (a * b) = bintrunc (LENGTH('a)) (uint a * uint b)"
  1207     and "uint (- a) = bintrunc (len_of TYPE('a)) (- uint a)"
  1207     and "uint (- a) = bintrunc (LENGTH('a)) (- uint a)"
  1208     and "uint (word_succ a) = bintrunc (len_of TYPE('a)) (uint a + 1)"
  1208     and "uint (word_succ a) = bintrunc (LENGTH('a)) (uint a + 1)"
  1209     and "uint (word_pred a) = bintrunc (len_of TYPE('a)) (uint a - 1)"
  1209     and "uint (word_pred a) = bintrunc (LENGTH('a)) (uint a - 1)"
  1210     and "uint (0 :: 'a word) = bintrunc (len_of TYPE('a)) 0"
  1210     and "uint (0 :: 'a word) = bintrunc (LENGTH('a)) 0"
  1211     and "uint (1 :: 'a word) = bintrunc (len_of TYPE('a)) 1"
  1211     and "uint (1 :: 'a word) = bintrunc (LENGTH('a)) 1"
  1212   by (simp_all add: uint_word_ariths bintrunc_mod2p)
  1212   by (simp_all add: uint_word_ariths bintrunc_mod2p)
  1213 
  1213 
  1214 lemma sint_word_ariths:
  1214 lemma sint_word_ariths:
  1215   fixes a b :: "'a::len word"
  1215   fixes a b :: "'a::len word"
  1216   shows "sint (a + b) = sbintrunc (len_of TYPE('a) - 1) (sint a + sint b)"
  1216   shows "sint (a + b) = sbintrunc (LENGTH('a) - 1) (sint a + sint b)"
  1217     and "sint (a - b) = sbintrunc (len_of TYPE('a) - 1) (sint a - sint b)"
  1217     and "sint (a - b) = sbintrunc (LENGTH('a) - 1) (sint a - sint b)"
  1218     and "sint (a * b) = sbintrunc (len_of TYPE('a) - 1) (sint a * sint b)"
  1218     and "sint (a * b) = sbintrunc (LENGTH('a) - 1) (sint a * sint b)"
  1219     and "sint (- a) = sbintrunc (len_of TYPE('a) - 1) (- sint a)"
  1219     and "sint (- a) = sbintrunc (LENGTH('a) - 1) (- sint a)"
  1220     and "sint (word_succ a) = sbintrunc (len_of TYPE('a) - 1) (sint a + 1)"
  1220     and "sint (word_succ a) = sbintrunc (LENGTH('a) - 1) (sint a + 1)"
  1221     and "sint (word_pred a) = sbintrunc (len_of TYPE('a) - 1) (sint a - 1)"
  1221     and "sint (word_pred a) = sbintrunc (LENGTH('a) - 1) (sint a - 1)"
  1222     and "sint (0 :: 'a word) = sbintrunc (len_of TYPE('a) - 1) 0"
  1222     and "sint (0 :: 'a word) = sbintrunc (LENGTH('a) - 1) 0"
  1223     and "sint (1 :: 'a word) = sbintrunc (len_of TYPE('a) - 1) 1"
  1223     and "sint (1 :: 'a word) = sbintrunc (LENGTH('a) - 1) 1"
  1224          apply (simp_all only: word_sbin.inverse_norm [symmetric])
  1224          apply (simp_all only: word_sbin.inverse_norm [symmetric])
  1225          apply (simp_all add: wi_hom_syms)
  1225          apply (simp_all add: wi_hom_syms)
  1226    apply transfer apply simp
  1226    apply transfer apply simp
  1227   apply transfer apply simp
  1227   apply transfer apply simp
  1228   done
  1228   done
  1282   unfolding unat_def word_less_alt
  1282   unfolding unat_def word_less_alt
  1283   by (rule nat_less_eq_zless [symmetric]) simp
  1283   by (rule nat_less_eq_zless [symmetric]) simp
  1284 
  1284 
  1285 lemma wi_less:
  1285 lemma wi_less:
  1286   "(word_of_int n < (word_of_int m :: 'a::len0 word)) =
  1286   "(word_of_int n < (word_of_int m :: 'a::len0 word)) =
  1287     (n mod 2 ^ len_of TYPE('a) < m mod 2 ^ len_of TYPE('a))"
  1287     (n mod 2 ^ LENGTH('a) < m mod 2 ^ LENGTH('a))"
  1288   unfolding word_less_alt by (simp add: word_uint.eq_norm)
  1288   unfolding word_less_alt by (simp add: word_uint.eq_norm)
  1289 
  1289 
  1290 lemma wi_le:
  1290 lemma wi_le:
  1291   "(word_of_int n \<le> (word_of_int m :: 'a::len0 word)) =
  1291   "(word_of_int n \<le> (word_of_int m :: 'a::len0 word)) =
  1292     (n mod 2 ^ len_of TYPE('a) \<le> m mod 2 ^ len_of TYPE('a))"
  1292     (n mod 2 ^ LENGTH('a) \<le> m mod 2 ^ LENGTH('a))"
  1293   unfolding word_le_def by (simp add: word_uint.eq_norm)
  1293   unfolding word_le_def by (simp add: word_uint.eq_norm)
  1294 
  1294 
  1295 lemma udvd_nat_alt: "a udvd b \<longleftrightarrow> (\<exists>n\<ge>0. unat b = n * unat a)"
  1295 lemma udvd_nat_alt: "a udvd b \<longleftrightarrow> (\<exists>n\<ge>0. unat b = n * unat a)"
  1296   apply (unfold udvd_def)
  1296   apply (unfold udvd_def)
  1297   apply safe
  1297   apply safe
  1317   have "0 \<le> uint w" by (fact uint_nonnegative)
  1317   have "0 \<le> uint w" by (fact uint_nonnegative)
  1318   moreover from assms have "0 \<noteq> uint w"
  1318   moreover from assms have "0 \<noteq> uint w"
  1319     by (simp add: uint_0_iff)
  1319     by (simp add: uint_0_iff)
  1320   ultimately have "1 \<le> uint w"
  1320   ultimately have "1 \<le> uint w"
  1321     by arith
  1321     by arith
  1322   from uint_lt2p [of w] have "uint w - 1 < 2 ^ len_of TYPE('a)"
  1322   from uint_lt2p [of w] have "uint w - 1 < 2 ^ LENGTH('a)"
  1323     by arith
  1323     by arith
  1324   with \<open>1 \<le> uint w\<close> have "(uint w - 1) mod 2 ^ len_of TYPE('a) = uint w - 1"
  1324   with \<open>1 \<le> uint w\<close> have "(uint w - 1) mod 2 ^ LENGTH('a) = uint w - 1"
  1325     by (auto intro: mod_pos_pos_trivial)
  1325     by (auto intro: mod_pos_pos_trivial)
  1326   with \<open>1 \<le> uint w\<close> have "nat ((uint w - 1) mod 2 ^ len_of TYPE('a)) = nat (uint w) - 1"
  1326   with \<open>1 \<le> uint w\<close> have "nat ((uint w - 1) mod 2 ^ LENGTH('a)) = nat (uint w) - 1"
  1327     by auto
  1327     by auto
  1328   then show ?thesis
  1328   then show ?thesis
  1329     by (simp only: unat_def int_word_uint word_arith_wis mod_diff_right_eq)
  1329     by (simp only: unat_def int_word_uint word_arith_wis mod_diff_right_eq)
  1330 qed
  1330 qed
  1331 
  1331 
  1333   by (simp add: unat_minus_one) (simp add: unat_0_iff [symmetric])
  1333   by (simp add: unat_minus_one) (simp add: unat_0_iff [symmetric])
  1334 
  1334 
  1335 lemmas uint_add_ge0 [simp] = add_nonneg_nonneg [OF uint_ge_0 uint_ge_0]
  1335 lemmas uint_add_ge0 [simp] = add_nonneg_nonneg [OF uint_ge_0 uint_ge_0]
  1336 lemmas uint_mult_ge0 [simp] = mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0]
  1336 lemmas uint_mult_ge0 [simp] = mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0]
  1337 
  1337 
  1338 lemma uint_sub_lt2p [simp]: "uint x - uint y < 2 ^ len_of TYPE('a)"
  1338 lemma uint_sub_lt2p [simp]: "uint x - uint y < 2 ^ LENGTH('a)"
  1339   for x :: "'a::len0 word" and y :: "'b::len0 word"
  1339   for x :: "'a::len0 word" and y :: "'b::len0 word"
  1340   using uint_ge_0 [of y] uint_lt2p [of x] by arith
  1340   using uint_ge_0 [of y] uint_lt2p [of x] by arith
  1341 
  1341 
  1342 
  1342 
  1343 subsection \<open>Conditions for the addition (etc) of two words to overflow\<close>
  1343 subsection \<open>Conditions for the addition (etc) of two words to overflow\<close>
  1344 
  1344 
  1345 lemma uint_add_lem:
  1345 lemma uint_add_lem:
  1346   "(uint x + uint y < 2 ^ len_of TYPE('a)) =
  1346   "(uint x + uint y < 2 ^ LENGTH('a)) =
  1347     (uint (x + y) = uint x + uint y)"
  1347     (uint (x + y) = uint x + uint y)"
  1348   for x y :: "'a::len0 word"
  1348   for x y :: "'a::len0 word"
  1349   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
  1349   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
  1350 
  1350 
  1351 lemma uint_mult_lem:
  1351 lemma uint_mult_lem:
  1352   "(uint x * uint y < 2 ^ len_of TYPE('a)) =
  1352   "(uint x * uint y < 2 ^ LENGTH('a)) =
  1353     (uint (x * y) = uint x * uint y)"
  1353     (uint (x * y) = uint x * uint y)"
  1354   for x y :: "'a::len0 word"
  1354   for x y :: "'a::len0 word"
  1355   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
  1355   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
  1356 
  1356 
  1357 lemma uint_sub_lem: "uint x \<ge> uint y \<longleftrightarrow> uint (x - y) = uint x - uint y"
  1357 lemma uint_sub_lem: "uint x \<ge> uint y \<longleftrightarrow> uint (x - y) = uint x - uint y"
  1369   for x y z :: int
  1369   for x y z :: int
  1370   by (auto intro: int_mod_eq)
  1370   by (auto intro: int_mod_eq)
  1371 
  1371 
  1372 lemma uint_plus_if':
  1372 lemma uint_plus_if':
  1373   "uint (a + b) =
  1373   "uint (a + b) =
  1374     (if uint a + uint b < 2 ^ len_of TYPE('a) then uint a + uint b
  1374     (if uint a + uint b < 2 ^ LENGTH('a) then uint a + uint b
  1375      else uint a + uint b - 2 ^ len_of TYPE('a))"
  1375      else uint a + uint b - 2 ^ LENGTH('a))"
  1376   for a b :: "'a::len0 word"
  1376   for a b :: "'a::len0 word"
  1377   using mod_add_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths)
  1377   using mod_add_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths)
  1378 
  1378 
  1379 lemma mod_sub_if_z:
  1379 lemma mod_sub_if_z:
  1380   "x < z \<Longrightarrow> y < z \<Longrightarrow> 0 \<le> y \<Longrightarrow> 0 \<le> x \<Longrightarrow> 0 \<le> z \<Longrightarrow>
  1380   "x < z \<Longrightarrow> y < z \<Longrightarrow> 0 \<le> y \<Longrightarrow> 0 \<le> x \<Longrightarrow> 0 \<le> z \<Longrightarrow>
  1383   by (auto intro: int_mod_eq)
  1383   by (auto intro: int_mod_eq)
  1384 
  1384 
  1385 lemma uint_sub_if':
  1385 lemma uint_sub_if':
  1386   "uint (a - b) =
  1386   "uint (a - b) =
  1387     (if uint b \<le> uint a then uint a - uint b
  1387     (if uint b \<le> uint a then uint a - uint b
  1388      else uint a - uint b + 2 ^ len_of TYPE('a))"
  1388      else uint a - uint b + 2 ^ LENGTH('a))"
  1389   for a b :: "'a::len0 word"
  1389   for a b :: "'a::len0 word"
  1390   using mod_sub_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths)
  1390   using mod_sub_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths)
  1391 
  1391 
  1392 
  1392 
  1393 subsection \<open>Definition of \<open>uint_arith\<close>\<close>
  1393 subsection \<open>Definition of \<open>uint_arith\<close>\<close>
  1394 
  1394 
  1395 lemma word_of_int_inverse:
  1395 lemma word_of_int_inverse:
  1396   "word_of_int r = a \<Longrightarrow> 0 \<le> r \<Longrightarrow> r < 2 ^ len_of TYPE('a) \<Longrightarrow> uint a = r"
  1396   "word_of_int r = a \<Longrightarrow> 0 \<le> r \<Longrightarrow> r < 2 ^ LENGTH('a) \<Longrightarrow> uint a = r"
  1397   for a :: "'a::len0 word"
  1397   for a :: "'a::len0 word"
  1398   apply (erule word_uint.Abs_inverse' [rotated])
  1398   apply (erule word_uint.Abs_inverse' [rotated])
  1399   apply (simp add: uints_num)
  1399   apply (simp add: uints_num)
  1400   done
  1400   done
  1401 
  1401 
  1402 lemma uint_split:
  1402 lemma uint_split:
  1403   "P (uint x) = (\<forall>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^len_of TYPE('a) \<longrightarrow> P i)"
  1403   "P (uint x) = (\<forall>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^LENGTH('a) \<longrightarrow> P i)"
  1404   for x :: "'a::len0 word"
  1404   for x :: "'a::len0 word"
  1405   apply (fold word_int_case_def)
  1405   apply (fold word_int_case_def)
  1406   apply (auto dest!: word_of_int_inverse simp: int_word_uint mod_pos_pos_trivial
  1406   apply (auto dest!: word_of_int_inverse simp: int_word_uint mod_pos_pos_trivial
  1407       split: word_int_split)
  1407       split: word_int_split)
  1408   done
  1408   done
  1409 
  1409 
  1410 lemma uint_split_asm:
  1410 lemma uint_split_asm:
  1411   "P (uint x) = (\<nexists>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^len_of TYPE('a) \<and> \<not> P i)"
  1411   "P (uint x) = (\<nexists>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^LENGTH('a) \<and> \<not> P i)"
  1412   for x :: "'a::len0 word"
  1412   for x :: "'a::len0 word"
  1413   by (auto dest!: word_of_int_inverse
  1413   by (auto dest!: word_of_int_inverse
  1414       simp: int_word_uint mod_pos_pos_trivial
  1414       simp: int_word_uint mod_pos_pos_trivial
  1415       split: uint_split)
  1415       split: uint_split)
  1416 
  1416 
  1419 lemmas uint_arith_simps =
  1419 lemmas uint_arith_simps =
  1420   word_le_def word_less_alt
  1420   word_le_def word_less_alt
  1421   word_uint.Rep_inject [symmetric]
  1421   word_uint.Rep_inject [symmetric]
  1422   uint_sub_if' uint_plus_if'
  1422   uint_sub_if' uint_plus_if'
  1423 
  1423 
  1424 \<comment> \<open>use this to stop, eg. \<open>2 ^ len_of TYPE(32)\<close> being simplified\<close>
  1424 \<comment> \<open>use this to stop, eg. \<open>2 ^ LENGTH(32)\<close> being simplified\<close>
  1425 lemma power_False_cong: "False \<Longrightarrow> a ^ b = c ^ d"
  1425 lemma power_False_cong: "False \<Longrightarrow> a ^ b = c ^ d"
  1426   by auto
  1426   by auto
  1427 
  1427 
  1428 \<comment> \<open>\<open>uint_arith_tac\<close>: reduce to arithmetic on int, try to solve by arith\<close>
  1428 \<comment> \<open>\<open>uint_arith_tac\<close>: reduce to arithmetic on int, try to solve by arith\<close>
  1429 ML \<open>
  1429 ML \<open>
  1472 
  1472 
  1473 lemma no_ulen_sub: "x \<ge> x - y \<longleftrightarrow> uint y \<le> uint x"
  1473 lemma no_ulen_sub: "x \<ge> x - y \<longleftrightarrow> uint y \<le> uint x"
  1474   for x y :: "'a::len0 word"
  1474   for x y :: "'a::len0 word"
  1475   by uint_arith
  1475   by uint_arith
  1476 
  1476 
  1477 lemma no_olen_add': "x \<le> y + x \<longleftrightarrow> uint y + uint x < 2 ^ len_of TYPE('a)"
  1477 lemma no_olen_add': "x \<le> y + x \<longleftrightarrow> uint y + uint x < 2 ^ LENGTH('a)"
  1478   for x y :: "'a::len0 word"
  1478   for x y :: "'a::len0 word"
  1479   by (simp add: ac_simps no_olen_add)
  1479   by (simp add: ac_simps no_olen_add)
  1480 
  1480 
  1481 lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric]]
  1481 lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric]]
  1482 
  1482 
  1694   note that \<open>iszero_def\<close> is only for class \<open>comm_semiring_1_cancel\<close>,
  1694   note that \<open>iszero_def\<close> is only for class \<open>comm_semiring_1_cancel\<close>,
  1695   which requires word length \<open>\<ge> 1\<close>, ie \<open>'a::len word\<close>
  1695   which requires word length \<open>\<ge> 1\<close>, ie \<open>'a::len word\<close>
  1696 \<close>
  1696 \<close>
  1697 lemma iszero_word_no [simp]:
  1697 lemma iszero_word_no [simp]:
  1698   "iszero (numeral bin :: 'a::len word) =
  1698   "iszero (numeral bin :: 'a::len word) =
  1699     iszero (bintrunc (len_of TYPE('a)) (numeral bin))"
  1699     iszero (bintrunc (LENGTH('a)) (numeral bin))"
  1700   using word_ubin.norm_eq_iff [where 'a='a, of "numeral bin" 0]
  1700   using word_ubin.norm_eq_iff [where 'a='a, of "numeral bin" 0]
  1701   by (simp add: iszero_def [symmetric])
  1701   by (simp add: iszero_def [symmetric])
  1702 
  1702 
  1703 text \<open>Use \<open>iszero\<close> to simplify equalities between word numerals.\<close>
  1703 text \<open>Use \<open>iszero\<close> to simplify equalities between word numerals.\<close>
  1704 
  1704 
  1707 
  1707 
  1708 
  1708 
  1709 subsection \<open>Word and nat\<close>
  1709 subsection \<open>Word and nat\<close>
  1710 
  1710 
  1711 lemma td_ext_unat [OF refl]:
  1711 lemma td_ext_unat [OF refl]:
  1712   "n = len_of TYPE('a::len) \<Longrightarrow>
  1712   "n = LENGTH('a::len) \<Longrightarrow>
  1713     td_ext (unat :: 'a word \<Rightarrow> nat) of_nat (unats n) (\<lambda>i. i mod 2 ^ n)"
  1713     td_ext (unat :: 'a word \<Rightarrow> nat) of_nat (unats n) (\<lambda>i. i mod 2 ^ n)"
  1714   apply (unfold td_ext_def' unat_def word_of_nat unats_uints)
  1714   apply (unfold td_ext_def' unat_def word_of_nat unats_uints)
  1715   apply (auto intro!: imageI simp add : word_of_int_hom_syms)
  1715   apply (auto intro!: imageI simp add : word_of_int_hom_syms)
  1716    apply (erule word_uint.Abs_inverse [THEN arg_cong])
  1716    apply (erule word_uint.Abs_inverse [THEN arg_cong])
  1717   apply (simp add: int_word_uint nat_mod_distrib nat_power_eq)
  1717   apply (simp add: int_word_uint nat_mod_distrib nat_power_eq)
  1721 
  1721 
  1722 interpretation word_unat:
  1722 interpretation word_unat:
  1723   td_ext
  1723   td_ext
  1724     "unat::'a::len word \<Rightarrow> nat"
  1724     "unat::'a::len word \<Rightarrow> nat"
  1725     of_nat
  1725     of_nat
  1726     "unats (len_of TYPE('a::len))"
  1726     "unats (LENGTH('a::len))"
  1727     "\<lambda>i. i mod 2 ^ len_of TYPE('a::len)"
  1727     "\<lambda>i. i mod 2 ^ LENGTH('a::len)"
  1728   by (rule td_ext_unat)
  1728   by (rule td_ext_unat)
  1729 
  1729 
  1730 lemmas td_unat = word_unat.td_thm
  1730 lemmas td_unat = word_unat.td_thm
  1731 
  1731 
  1732 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq]
  1732 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq]
  1733 
  1733 
  1734 lemma unat_le: "y \<le> unat z \<Longrightarrow> y \<in> unats (len_of TYPE('a))"
  1734 lemma unat_le: "y \<le> unat z \<Longrightarrow> y \<in> unats (LENGTH('a))"
  1735   for z :: "'a::len word"
  1735   for z :: "'a::len word"
  1736   apply (unfold unats_def)
  1736   apply (unfold unats_def)
  1737   apply clarsimp
  1737   apply clarsimp
  1738   apply (rule xtrans, rule unat_lt2p, assumption)
  1738   apply (rule xtrans, rule unat_lt2p, assumption)
  1739   done
  1739   done
  1740 
  1740 
  1741 lemma word_nchotomy: "\<forall>w :: 'a::len word. \<exists>n. w = of_nat n \<and> n < 2 ^ len_of TYPE('a)"
  1741 lemma word_nchotomy: "\<forall>w :: 'a::len word. \<exists>n. w = of_nat n \<and> n < 2 ^ LENGTH('a)"
  1742   apply (rule allI)
  1742   apply (rule allI)
  1743   apply (rule word_unat.Abs_cases)
  1743   apply (rule word_unat.Abs_cases)
  1744   apply (unfold unats_def)
  1744   apply (unfold unats_def)
  1745   apply auto
  1745   apply auto
  1746   done
  1746   done
  1747 
  1747 
  1748 lemma of_nat_eq: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ len_of TYPE('a))"
  1748 lemma of_nat_eq: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ LENGTH('a))"
  1749   for w :: "'a::len word"
  1749   for w :: "'a::len word"
  1750   using mod_div_mult_eq [of n "2 ^ LENGTH('a)", symmetric]
  1750   using mod_div_mult_eq [of n "2 ^ LENGTH('a)", symmetric]
  1751   by (auto simp add: word_unat.inverse_norm)
  1751   by (auto simp add: word_unat.inverse_norm)
  1752 
  1752 
  1753 lemma of_nat_eq_size: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ size w)"
  1753 lemma of_nat_eq_size: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ size w)"
  1754   unfolding word_size by (rule of_nat_eq)
  1754   unfolding word_size by (rule of_nat_eq)
  1755 
  1755 
  1756 lemma of_nat_0: "of_nat m = (0::'a::len word) \<longleftrightarrow> (\<exists>q. m = q * 2 ^ len_of TYPE('a))"
  1756 lemma of_nat_0: "of_nat m = (0::'a::len word) \<longleftrightarrow> (\<exists>q. m = q * 2 ^ LENGTH('a))"
  1757   by (simp add: of_nat_eq)
  1757   by (simp add: of_nat_eq)
  1758 
  1758 
  1759 lemma of_nat_2p [simp]: "of_nat (2 ^ len_of TYPE('a)) = (0::'a::len word)"
  1759 lemma of_nat_2p [simp]: "of_nat (2 ^ LENGTH('a)) = (0::'a::len word)"
  1760   by (fact mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]])
  1760   by (fact mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]])
  1761 
  1761 
  1762 lemma of_nat_gt_0: "of_nat k \<noteq> 0 \<Longrightarrow> 0 < k"
  1762 lemma of_nat_gt_0: "of_nat k \<noteq> 0 \<Longrightarrow> 0 < k"
  1763   by (cases k) auto
  1763   by (cases k) auto
  1764 
  1764 
  1765 lemma of_nat_neq_0: "0 < k \<Longrightarrow> k < 2 ^ len_of TYPE('a::len) \<Longrightarrow> of_nat k \<noteq> (0 :: 'a word)"
  1765 lemma of_nat_neq_0: "0 < k \<Longrightarrow> k < 2 ^ LENGTH('a::len) \<Longrightarrow> of_nat k \<noteq> (0 :: 'a word)"
  1766   by (auto simp add : of_nat_0)
  1766   by (auto simp add : of_nat_0)
  1767 
  1767 
  1768 lemma Abs_fnat_hom_add: "of_nat a + of_nat b = of_nat (a + b)"
  1768 lemma Abs_fnat_hom_add: "of_nat a + of_nat b = of_nat (a + b)"
  1769   by simp
  1769   by simp
  1770 
  1770 
  1813 
  1813 
  1814 lemmas word_sub_less_iff = word_sub_le_iff
  1814 lemmas word_sub_less_iff = word_sub_le_iff
  1815   [unfolded linorder_not_less [symmetric] Not_eq_iff]
  1815   [unfolded linorder_not_less [symmetric] Not_eq_iff]
  1816 
  1816 
  1817 lemma unat_add_lem:
  1817 lemma unat_add_lem:
  1818   "unat x + unat y < 2 ^ len_of TYPE('a) \<longleftrightarrow> unat (x + y) = unat x + unat y"
  1818   "unat x + unat y < 2 ^ LENGTH('a) \<longleftrightarrow> unat (x + y) = unat x + unat y"
  1819   for x y :: "'a::len word"
  1819   for x y :: "'a::len word"
  1820   by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem])
  1820   by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem])
  1821 
  1821 
  1822 lemma unat_mult_lem:
  1822 lemma unat_mult_lem:
  1823   "unat x * unat y < 2 ^ len_of TYPE('a) \<longleftrightarrow> unat (x * y) = unat x * unat y"
  1823   "unat x * unat y < 2 ^ LENGTH('a) \<longleftrightarrow> unat (x * y) = unat x * unat y"
  1824   for x y :: "'a::len word"
  1824   for x y :: "'a::len word"
  1825   by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem])
  1825   by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem])
  1826 
  1826 
  1827 lemmas unat_plus_if' =
  1827 lemmas unat_plus_if' =
  1828   trans [OF unat_word_ariths(1) mod_nat_add, simplified]
  1828   trans [OF unat_word_ariths(1) mod_nat_add, simplified]
  1883   for x y :: "'a::len word"
  1883   for x y :: "'a::len word"
  1884   by (simp add: uint_nat unat_mod zmod_int)
  1884   by (simp add: uint_nat unat_mod zmod_int)
  1885 
  1885 
  1886 text \<open>Definition of \<open>unat_arith\<close> tactic\<close>
  1886 text \<open>Definition of \<open>unat_arith\<close> tactic\<close>
  1887 
  1887 
  1888 lemma unat_split: "P (unat x) \<longleftrightarrow> (\<forall>n. of_nat n = x \<and> n < 2^len_of TYPE('a) \<longrightarrow> P n)"
  1888 lemma unat_split: "P (unat x) \<longleftrightarrow> (\<forall>n. of_nat n = x \<and> n < 2^LENGTH('a) \<longrightarrow> P n)"
  1889   for x :: "'a::len word"
  1889   for x :: "'a::len word"
  1890   by (auto simp: unat_of_nat)
  1890   by (auto simp: unat_of_nat)
  1891 
  1891 
  1892 lemma unat_split_asm: "P (unat x) \<longleftrightarrow> (\<nexists>n. of_nat n = x \<and> n < 2^len_of TYPE('a) \<and> \<not> P n)"
  1892 lemma unat_split_asm: "P (unat x) \<longleftrightarrow> (\<nexists>n. of_nat n = x \<and> n < 2^LENGTH('a) \<and> \<not> P n)"
  1893   for x :: "'a::len word"
  1893   for x :: "'a::len word"
  1894   by (auto simp: unat_of_nat)
  1894   by (auto simp: unat_of_nat)
  1895 
  1895 
  1896 lemmas of_nat_inverse =
  1896 lemmas of_nat_inverse =
  1897   word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified]
  1897   word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified]
  1945   no_plus_overflow_unat_size [unfolded word_size]
  1945   no_plus_overflow_unat_size [unfolded word_size]
  1946 
  1946 
  1947 lemmas unat_plus_simple =
  1947 lemmas unat_plus_simple =
  1948   trans [OF no_olen_add_nat unat_add_lem]
  1948   trans [OF no_olen_add_nat unat_add_lem]
  1949 
  1949 
  1950 lemma word_div_mult: "0 < y \<Longrightarrow> unat x * unat y < 2 ^ len_of TYPE('a) \<Longrightarrow> x * y div y = x"
  1950 lemma word_div_mult: "0 < y \<Longrightarrow> unat x * unat y < 2 ^ LENGTH('a) \<Longrightarrow> x * y div y = x"
  1951   for x y :: "'a::len word"
  1951   for x y :: "'a::len word"
  1952   apply unat_arith
  1952   apply unat_arith
  1953   apply clarsimp
  1953   apply clarsimp
  1954   apply (subst unat_mult_lem [THEN iffD1])
  1954   apply (subst unat_mult_lem [THEN iffD1])
  1955    apply auto
  1955    apply auto
  1956   done
  1956   done
  1957 
  1957 
  1958 lemma div_lt': "i \<le> k div x \<Longrightarrow> unat i * unat x < 2 ^ len_of TYPE('a)"
  1958 lemma div_lt': "i \<le> k div x \<Longrightarrow> unat i * unat x < 2 ^ LENGTH('a)"
  1959   for i k x :: "'a::len word"
  1959   for i k x :: "'a::len word"
  1960   apply unat_arith
  1960   apply unat_arith
  1961   apply clarsimp
  1961   apply clarsimp
  1962   apply (drule mult_le_mono1)
  1962   apply (drule mult_le_mono1)
  1963   apply (erule order_le_less_trans)
  1963   apply (erule order_le_less_trans)
  1982   apply (drule mult_le_mono1)
  1982   apply (drule mult_le_mono1)
  1983   apply (erule order_trans)
  1983   apply (erule order_trans)
  1984   apply (rule div_mult_le)
  1984   apply (rule div_mult_le)
  1985   done
  1985   done
  1986 
  1986 
  1987 lemma div_lt_uint': "i \<le> k div x \<Longrightarrow> uint i * uint x < 2 ^ len_of TYPE('a)"
  1987 lemma div_lt_uint': "i \<le> k div x \<Longrightarrow> uint i * uint x < 2 ^ LENGTH('a)"
  1988   for i k x :: "'a::len word"
  1988   for i k x :: "'a::len word"
  1989   apply (unfold uint_nat)
  1989   apply (unfold uint_nat)
  1990   apply (drule div_lt')
  1990   apply (drule div_lt')
  1991   apply (metis of_nat_less_iff of_nat_mult of_nat_numeral of_nat_power)
  1991   apply (metis of_nat_less_iff of_nat_mult of_nat_numeral of_nat_power)
  1992   done
  1992   done
  1993 
  1993 
  1994 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint']
  1994 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint']
  1995 
  1995 
  1996 lemma word_le_exists': "x \<le> y \<Longrightarrow> \<exists>z. y = x + z \<and> uint x + uint z < 2 ^ len_of TYPE('a)"
  1996 lemma word_le_exists': "x \<le> y \<Longrightarrow> \<exists>z. y = x + z \<and> uint x + uint z < 2 ^ LENGTH('a)"
  1997   for x y z :: "'a::len0 word"
  1997   for x y z :: "'a::len0 word"
  1998   apply (rule exI)
  1998   apply (rule exI)
  1999   apply (rule conjI)
  1999   apply (rule conjI)
  2000    apply (rule zadd_diff_inverse)
  2000    apply (rule zadd_diff_inverse)
  2001   apply uint_arith
  2001   apply uint_arith
  2048 
  2048 
  2049 lemma word_arith_power_alt: "a ^ n = (word_of_int (uint a ^ n) :: 'a::len word)"
  2049 lemma word_arith_power_alt: "a ^ n = (word_of_int (uint a ^ n) :: 'a::len word)"
  2050   by (simp add : word_of_int_power_hom [symmetric])
  2050   by (simp add : word_of_int_power_hom [symmetric])
  2051 
  2051 
  2052 lemma of_bl_length_less:
  2052 lemma of_bl_length_less:
  2053   "length x = k \<Longrightarrow> k < len_of TYPE('a) \<Longrightarrow> (of_bl x :: 'a::len word) < 2 ^ k"
  2053   "length x = k \<Longrightarrow> k < LENGTH('a) \<Longrightarrow> (of_bl x :: 'a::len word) < 2 ^ k"
  2054   apply (unfold of_bl_def word_less_alt word_numeral_alt)
  2054   apply (unfold of_bl_def word_less_alt word_numeral_alt)
  2055   apply safe
  2055   apply safe
  2056   apply (simp (no_asm) add: word_of_int_power_hom word_uint.eq_norm
  2056   apply (simp (no_asm) add: word_of_int_power_hom word_uint.eq_norm
  2057       del: word_of_int_numeral)
  2057       del: word_of_int_numeral)
  2058   apply (simp add: mod_pos_pos_trivial)
  2058   apply (simp add: mod_pos_pos_trivial)
  2155 
  2155 
  2156 lemma uint_and: "uint (x AND y) = uint x AND uint y"
  2156 lemma uint_and: "uint (x AND y) = uint x AND uint y"
  2157   by (transfer, simp add: bin_trunc_ao)
  2157   by (transfer, simp add: bin_trunc_ao)
  2158 
  2158 
  2159 lemma test_bit_wi [simp]:
  2159 lemma test_bit_wi [simp]:
  2160   "(word_of_int x :: 'a::len0 word) !! n \<longleftrightarrow> n < len_of TYPE('a) \<and> bin_nth x n"
  2160   "(word_of_int x :: 'a::len0 word) !! n \<longleftrightarrow> n < LENGTH('a) \<and> bin_nth x n"
  2161   by (simp add: word_test_bit_def word_ubin.eq_norm nth_bintr)
  2161   by (simp add: word_test_bit_def word_ubin.eq_norm nth_bintr)
  2162 
  2162 
  2163 lemma word_test_bit_transfer [transfer_rule]:
  2163 lemma word_test_bit_transfer [transfer_rule]:
  2164   "(rel_fun pcr_word (rel_fun (=) (=)))
  2164   "(rel_fun pcr_word (rel_fun (=) (=)))
  2165     (\<lambda>x n. n < len_of TYPE('a) \<and> bin_nth x n) (test_bit :: 'a::len0 word \<Rightarrow> _)"
  2165     (\<lambda>x n. n < LENGTH('a) \<and> bin_nth x n) (test_bit :: 'a::len0 word \<Rightarrow> _)"
  2166   unfolding rel_fun_def word.pcr_cr_eq cr_word_def by simp
  2166   unfolding rel_fun_def word.pcr_cr_eq cr_word_def by simp
  2167 
  2167 
  2168 lemma word_ops_nth_size:
  2168 lemma word_ops_nth_size:
  2169   "n < size x \<Longrightarrow>
  2169   "n < size x \<Longrightarrow>
  2170     (x OR y) !! n = (x !! n | y !! n) \<and>
  2170     (x OR y) !! n = (x !! n | y !! n) \<and>
  2180   for x :: "'a::len0 word"
  2180   for x :: "'a::len0 word"
  2181   by transfer (auto simp add: bin_nth_ops)
  2181   by transfer (auto simp add: bin_nth_ops)
  2182 
  2182 
  2183 lemma test_bit_numeral [simp]:
  2183 lemma test_bit_numeral [simp]:
  2184   "(numeral w :: 'a::len0 word) !! n \<longleftrightarrow>
  2184   "(numeral w :: 'a::len0 word) !! n \<longleftrightarrow>
  2185     n < len_of TYPE('a) \<and> bin_nth (numeral w) n"
  2185     n < LENGTH('a) \<and> bin_nth (numeral w) n"
  2186   by transfer (rule refl)
  2186   by transfer (rule refl)
  2187 
  2187 
  2188 lemma test_bit_neg_numeral [simp]:
  2188 lemma test_bit_neg_numeral [simp]:
  2189   "(- numeral w :: 'a::len0 word) !! n \<longleftrightarrow>
  2189   "(- numeral w :: 'a::len0 word) !! n \<longleftrightarrow>
  2190     n < len_of TYPE('a) \<and> bin_nth (- numeral w) n"
  2190     n < LENGTH('a) \<and> bin_nth (- numeral w) n"
  2191   by transfer (rule refl)
  2191   by transfer (rule refl)
  2192 
  2192 
  2193 lemma test_bit_1 [simp]: "(1 :: 'a::len word) !! n \<longleftrightarrow> n = 0"
  2193 lemma test_bit_1 [simp]: "(1 :: 'a::len word) !! n \<longleftrightarrow> n = 0"
  2194   by transfer auto
  2194   by transfer auto
  2195 
  2195 
  2196 lemma nth_0 [simp]: "\<not> (0 :: 'a::len0 word) !! n"
  2196 lemma nth_0 [simp]: "\<not> (0 :: 'a::len0 word) !! n"
  2197   by transfer simp
  2197   by transfer simp
  2198 
  2198 
  2199 lemma nth_minus1 [simp]: "(-1 :: 'a::len0 word) !! n \<longleftrightarrow> n < len_of TYPE('a)"
  2199 lemma nth_minus1 [simp]: "(-1 :: 'a::len0 word) !! n \<longleftrightarrow> n < LENGTH('a)"
  2200   by transfer simp
  2200   by transfer simp
  2201 
  2201 
  2202 \<comment> \<open>get from commutativity, associativity etc of \<open>int_and\<close> etc to same for \<open>word_and etc\<close>\<close>
  2202 \<comment> \<open>get from commutativity, associativity etc of \<open>int_and\<close> etc to same for \<open>word_and etc\<close>\<close>
  2203 lemmas bwsimps =
  2203 lemmas bwsimps =
  2204   wi_hom_add
  2204   wi_hom_add
  2342   by (auto simp: word_lsb_def bin_last_def)
  2342   by (auto simp: word_lsb_def bin_last_def)
  2343 
  2343 
  2344 lemma word_msb_sint: "msb w \<longleftrightarrow> sint w < 0"
  2344 lemma word_msb_sint: "msb w \<longleftrightarrow> sint w < 0"
  2345   by (simp only: word_msb_def sign_Min_lt_0)
  2345   by (simp only: word_msb_def sign_Min_lt_0)
  2346 
  2346 
  2347 lemma msb_word_of_int: "msb (word_of_int x::'a::len word) = bin_nth x (len_of TYPE('a) - 1)"
  2347 lemma msb_word_of_int: "msb (word_of_int x::'a::len word) = bin_nth x (LENGTH('a) - 1)"
  2348   by (simp add: word_msb_def word_sbin.eq_norm bin_sign_lem)
  2348   by (simp add: word_msb_def word_sbin.eq_norm bin_sign_lem)
  2349 
  2349 
  2350 lemma word_msb_numeral [simp]:
  2350 lemma word_msb_numeral [simp]:
  2351   "msb (numeral w::'a::len word) = bin_nth (numeral w) (len_of TYPE('a) - 1)"
  2351   "msb (numeral w::'a::len word) = bin_nth (numeral w) (LENGTH('a) - 1)"
  2352   unfolding word_numeral_alt by (rule msb_word_of_int)
  2352   unfolding word_numeral_alt by (rule msb_word_of_int)
  2353 
  2353 
  2354 lemma word_msb_neg_numeral [simp]:
  2354 lemma word_msb_neg_numeral [simp]:
  2355   "msb (- numeral w::'a::len word) = bin_nth (- numeral w) (len_of TYPE('a) - 1)"
  2355   "msb (- numeral w::'a::len word) = bin_nth (- numeral w) (LENGTH('a) - 1)"
  2356   unfolding word_neg_numeral_alt by (rule msb_word_of_int)
  2356   unfolding word_neg_numeral_alt by (rule msb_word_of_int)
  2357 
  2357 
  2358 lemma word_msb_0 [simp]: "\<not> msb (0::'a::len word)"
  2358 lemma word_msb_0 [simp]: "\<not> msb (0::'a::len word)"
  2359   by (simp add: word_msb_def)
  2359   by (simp add: word_msb_def)
  2360 
  2360 
  2361 lemma word_msb_1 [simp]: "msb (1::'a::len word) \<longleftrightarrow> len_of TYPE('a) = 1"
  2361 lemma word_msb_1 [simp]: "msb (1::'a::len word) \<longleftrightarrow> LENGTH('a) = 1"
  2362   unfolding word_1_wi msb_word_of_int eq_iff [where 'a=nat]
  2362   unfolding word_1_wi msb_word_of_int eq_iff [where 'a=nat]
  2363   by (simp add: Suc_le_eq)
  2363   by (simp add: Suc_le_eq)
  2364 
  2364 
  2365 lemma word_msb_nth: "msb w = bin_nth (uint w) (len_of TYPE('a) - 1)"
  2365 lemma word_msb_nth: "msb w = bin_nth (uint w) (LENGTH('a) - 1)"
  2366   for w :: "'a::len word"
  2366   for w :: "'a::len word"
  2367   by (simp add: word_msb_def sint_uint bin_sign_lem)
  2367   by (simp add: word_msb_def sint_uint bin_sign_lem)
  2368 
  2368 
  2369 lemma word_msb_alt: "msb w = hd (to_bl w)"
  2369 lemma word_msb_alt: "msb w = hd (to_bl w)"
  2370   for w :: "'a::len word"
  2370   for w :: "'a::len word"
  2413   done
  2413   done
  2414 
  2414 
  2415 lemma of_bl_rep_False: "of_bl (replicate n False @ bs) = of_bl bs"
  2415 lemma of_bl_rep_False: "of_bl (replicate n False @ bs) = of_bl bs"
  2416   by (auto simp: of_bl_def bl_to_bin_rep_F)
  2416   by (auto simp: of_bl_def bl_to_bin_rep_F)
  2417 
  2417 
  2418 lemma msb_nth: "msb w = w !! (len_of TYPE('a) - 1)"
  2418 lemma msb_nth: "msb w = w !! (LENGTH('a) - 1)"
  2419   for w :: "'a::len word"
  2419   for w :: "'a::len word"
  2420   by (simp add: word_msb_nth word_test_bit_def)
  2420   by (simp add: word_msb_nth word_test_bit_def)
  2421 
  2421 
  2422 lemmas msb0 = len_gt_0 [THEN diff_Suc_less, THEN word_ops_nth_size [unfolded word_size]]
  2422 lemmas msb0 = len_gt_0 [THEN diff_Suc_less, THEN word_ops_nth_size [unfolded word_size]]
  2423 lemmas msb1 = msb0 [where i = 0]
  2423 lemmas msb1 = msb0 [where i = 0]
  2448 
  2448 
  2449 interpretation test_bit:
  2449 interpretation test_bit:
  2450   td_ext
  2450   td_ext
  2451     "(!!) :: 'a::len0 word \<Rightarrow> nat \<Rightarrow> bool"
  2451     "(!!) :: 'a::len0 word \<Rightarrow> nat \<Rightarrow> bool"
  2452     set_bits
  2452     set_bits
  2453     "{f. \<forall>i. f i \<longrightarrow> i < len_of TYPE('a::len0)}"
  2453     "{f. \<forall>i. f i \<longrightarrow> i < LENGTH('a::len0)}"
  2454     "(\<lambda>h i. h i \<and> i < len_of TYPE('a::len0))"
  2454     "(\<lambda>h i. h i \<and> i < LENGTH('a::len0))"
  2455   by (rule td_ext_nth)
  2455   by (rule td_ext_nth)
  2456 
  2456 
  2457 lemmas td_nth = test_bit.td_thm
  2457 lemmas td_nth = test_bit.td_thm
  2458 
  2458 
  2459 lemma word_set_set_same [simp]: "set_bit (set_bit w n x) n y = set_bit w n y"
  2459 lemma word_set_set_same [simp]: "set_bit (set_bit w n x) n y = set_bit w n y"
  2466   shows "set_bit (set_bit w m x) n y = set_bit (set_bit w n y) m x"
  2466   shows "set_bit (set_bit w m x) n y = set_bit (set_bit w n y) m x"
  2467   by (rule word_eqI) (auto simp: test_bit_set_gen word_size assms)
  2467   by (rule word_eqI) (auto simp: test_bit_set_gen word_size assms)
  2468 
  2468 
  2469 lemma nth_sint:
  2469 lemma nth_sint:
  2470   fixes w :: "'a::len word"
  2470   fixes w :: "'a::len word"
  2471   defines "l \<equiv> len_of TYPE('a)"
  2471   defines "l \<equiv> LENGTH('a)"
  2472   shows "bin_nth (sint w) n = (if n < l - 1 then w !! n else w !! (l - 1))"
  2472   shows "bin_nth (sint w) n = (if n < l - 1 then w !! n else w !! (l - 1))"
  2473   unfolding sint_uint l_def
  2473   unfolding sint_uint l_def
  2474   by (auto simp: nth_sbintr word_test_bit_def [symmetric])
  2474   by (auto simp: nth_sbintr word_test_bit_def [symmetric])
  2475 
  2475 
  2476 lemma word_lsb_numeral [simp]:
  2476 lemma word_lsb_numeral [simp]:
  2506 
  2506 
  2507 lemma clearBit_no [simp]:
  2507 lemma clearBit_no [simp]:
  2508   "clearBit (numeral bin) n = word_of_int (bin_sc n False (numeral bin))"
  2508   "clearBit (numeral bin) n = word_of_int (bin_sc n False (numeral bin))"
  2509   by (simp add: clearBit_def)
  2509   by (simp add: clearBit_def)
  2510 
  2510 
  2511 lemma to_bl_n1: "to_bl (-1::'a::len0 word) = replicate (len_of TYPE('a)) True"
  2511 lemma to_bl_n1: "to_bl (-1::'a::len0 word) = replicate (LENGTH('a)) True"
  2512   apply (rule word_bl.Abs_inverse')
  2512   apply (rule word_bl.Abs_inverse')
  2513    apply simp
  2513    apply simp
  2514   apply (rule word_eqI)
  2514   apply (rule word_eqI)
  2515   apply (clarsimp simp add: word_size)
  2515   apply (clarsimp simp add: word_size)
  2516   apply (auto simp add: word_bl.Abs_inverse test_bit_bl word_size)
  2516   apply (auto simp add: word_bl.Abs_inverse test_bit_bl word_size)
  2532   apply (clarsimp simp add : test_bit_set_gen)
  2532   apply (clarsimp simp add : test_bit_set_gen)
  2533   apply (drule test_bit_size)
  2533   apply (drule test_bit_size)
  2534   apply force
  2534   apply force
  2535   done
  2535   done
  2536 
  2536 
  2537 lemma test_bit_2p: "(word_of_int (2 ^ n)::'a::len word) !! m \<longleftrightarrow> m = n \<and> m < len_of TYPE('a)"
  2537 lemma test_bit_2p: "(word_of_int (2 ^ n)::'a::len word) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a)"
  2538   by (auto simp: word_test_bit_def word_ubin.eq_norm nth_bintr nth_2p_bin)
  2538   by (auto simp: word_test_bit_def word_ubin.eq_norm nth_bintr nth_2p_bin)
  2539 
  2539 
  2540 lemma nth_w2p: "((2::'a::len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < len_of TYPE('a::len)"
  2540 lemma nth_w2p: "((2::'a::len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a::len)"
  2541   by (simp add: test_bit_2p [symmetric] word_of_int [symmetric])
  2541   by (simp add: test_bit_2p [symmetric] word_of_int [symmetric])
  2542 
  2542 
  2543 lemma uint_2p: "(0::'a::len word) < 2 ^ n \<Longrightarrow> uint (2 ^ n::'a::len word) = 2 ^ n"
  2543 lemma uint_2p: "(0::'a::len word) < 2 ^ n \<Longrightarrow> uint (2 ^ n::'a::len word) = 2 ^ n"
  2544   apply (unfold word_arith_power_alt)
  2544   apply (unfold word_arith_power_alt)
  2545   apply (case_tac "len_of TYPE('a)")
  2545   apply (case_tac "LENGTH('a)")
  2546    apply clarsimp
  2546    apply clarsimp
  2547   apply (case_tac "nat")
  2547   apply (case_tac "nat")
  2548    apply clarsimp
  2548    apply clarsimp
  2549    apply (case_tac "n")
  2549    apply (case_tac "n")
  2550     apply clarsimp
  2550     apply clarsimp
  2923   for w :: "'a::len word"
  2923   for w :: "'a::len word"
  2924   by (induct n) (auto simp: shiftl_def shiftl1_2t)
  2924   by (induct n) (auto simp: shiftl_def shiftl1_2t)
  2925 
  2925 
  2926 lemma shiftr1_bintr [simp]:
  2926 lemma shiftr1_bintr [simp]:
  2927   "(shiftr1 (numeral w) :: 'a::len0 word) =
  2927   "(shiftr1 (numeral w) :: 'a::len0 word) =
  2928     word_of_int (bin_rest (bintrunc (len_of TYPE('a)) (numeral w)))"
  2928     word_of_int (bin_rest (bintrunc (LENGTH('a)) (numeral w)))"
  2929   unfolding shiftr1_def word_numeral_alt by (simp add: word_ubin.eq_norm)
  2929   unfolding shiftr1_def word_numeral_alt by (simp add: word_ubin.eq_norm)
  2930 
  2930 
  2931 lemma sshiftr1_sbintr [simp]:
  2931 lemma sshiftr1_sbintr [simp]:
  2932   "(sshiftr1 (numeral w) :: 'a::len word) =
  2932   "(sshiftr1 (numeral w) :: 'a::len word) =
  2933     word_of_int (bin_rest (sbintrunc (len_of TYPE('a) - 1) (numeral w)))"
  2933     word_of_int (bin_rest (sbintrunc (LENGTH('a) - 1) (numeral w)))"
  2934   unfolding sshiftr1_def word_numeral_alt by (simp add: word_sbin.eq_norm)
  2934   unfolding sshiftr1_def word_numeral_alt by (simp add: word_sbin.eq_norm)
  2935 
  2935 
  2936 lemma shiftr_no [simp]:
  2936 lemma shiftr_no [simp]:
  2937   (* FIXME: neg_numeral *)
  2937   (* FIXME: neg_numeral *)
  2938   "(numeral w::'a::len0 word) >> n = word_of_int
  2938   "(numeral w::'a::len0 word) >> n = word_of_int
  2939     ((bin_rest ^^ n) (bintrunc (len_of TYPE('a)) (numeral w)))"
  2939     ((bin_rest ^^ n) (bintrunc (LENGTH('a)) (numeral w)))"
  2940   by (rule word_eqI) (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size)
  2940   by (rule word_eqI) (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size)
  2941 
  2941 
  2942 lemma sshiftr_no [simp]:
  2942 lemma sshiftr_no [simp]:
  2943   (* FIXME: neg_numeral *)
  2943   (* FIXME: neg_numeral *)
  2944   "(numeral w::'a::len word) >>> n = word_of_int
  2944   "(numeral w::'a::len word) >>> n = word_of_int
  2945     ((bin_rest ^^ n) (sbintrunc (len_of TYPE('a) - 1) (numeral w)))"
  2945     ((bin_rest ^^ n) (sbintrunc (LENGTH('a) - 1) (numeral w)))"
  2946   apply (rule word_eqI)
  2946   apply (rule word_eqI)
  2947   apply (auto simp: nth_sshiftr nth_rest_power_bin nth_sbintr word_size)
  2947   apply (auto simp: nth_sshiftr nth_rest_power_bin nth_sbintr word_size)
  2948    apply (subgoal_tac "na + n = len_of TYPE('a) - Suc 0", simp, simp)+
  2948    apply (subgoal_tac "na + n = LENGTH('a) - Suc 0", simp, simp)+
  2949   done
  2949   done
  2950 
  2950 
  2951 lemma shiftr1_bl_of:
  2951 lemma shiftr1_bl_of:
  2952   "length bl \<le> len_of TYPE('a) \<Longrightarrow>
  2952   "length bl \<le> LENGTH('a) \<Longrightarrow>
  2953     shiftr1 (of_bl bl::'a::len0 word) = of_bl (butlast bl)"
  2953     shiftr1 (of_bl bl::'a::len0 word) = of_bl (butlast bl)"
  2954   by (clarsimp simp: shiftr1_def of_bl_def butlast_rest_bl2bin word_ubin.eq_norm trunc_bl2bin)
  2954   by (clarsimp simp: shiftr1_def of_bl_def butlast_rest_bl2bin word_ubin.eq_norm trunc_bl2bin)
  2955 
  2955 
  2956 lemma shiftr_bl_of:
  2956 lemma shiftr_bl_of:
  2957   "length bl \<le> len_of TYPE('a) \<Longrightarrow>
  2957   "length bl \<le> LENGTH('a) \<Longrightarrow>
  2958     (of_bl bl::'a::len0 word) >> n = of_bl (take (length bl - n) bl)"
  2958     (of_bl bl::'a::len0 word) >> n = of_bl (take (length bl - n) bl)"
  2959   apply (unfold shiftr_def)
  2959   apply (unfold shiftr_def)
  2960   apply (induct n)
  2960   apply (induct n)
  2961    apply clarsimp
  2961    apply clarsimp
  2962   apply clarsimp
  2962   apply clarsimp
  2963   apply (subst shiftr1_bl_of)
  2963   apply (subst shiftr1_bl_of)
  2964    apply simp
  2964    apply simp
  2965   apply (simp add: butlast_take)
  2965   apply (simp add: butlast_take)
  2966   done
  2966   done
  2967 
  2967 
  2968 lemma shiftr_bl: "x >> n \<equiv> of_bl (take (len_of TYPE('a) - n) (to_bl x))"
  2968 lemma shiftr_bl: "x >> n \<equiv> of_bl (take (LENGTH('a) - n) (to_bl x))"
  2969   for x :: "'a::len0 word"
  2969   for x :: "'a::len0 word"
  2970   using shiftr_bl_of [where 'a='a, of "to_bl x"] by simp
  2970   using shiftr_bl_of [where 'a='a, of "to_bl x"] by simp
  2971 
  2971 
  2972 lemma msb_shift: "msb w \<longleftrightarrow> w >> (len_of TYPE('a) - 1) \<noteq> 0"
  2972 lemma msb_shift: "msb w \<longleftrightarrow> w >> (LENGTH('a) - 1) \<noteq> 0"
  2973   for w :: "'a::len word"
  2973   for w :: "'a::len word"
  2974   apply (unfold shiftr_bl word_msb_alt)
  2974   apply (unfold shiftr_bl word_msb_alt)
  2975   apply (simp add: word_size Suc_le_eq take_Suc)
  2975   apply (simp add: word_size Suc_le_eq take_Suc)
  2976   apply (cases "hd (to_bl w)")
  2976   apply (cases "hd (to_bl w)")
  2977    apply (auto simp: word_1_bl of_bl_rep_False [where n=1 and bs="[]", simplified])
  2977    apply (auto simp: word_1_bl of_bl_rep_False [where n=1 and bs="[]", simplified])
  3067 lemma and_mask_no: "numeral i AND mask n = word_of_int (bintrunc n (numeral i))"
  3067 lemma and_mask_no: "numeral i AND mask n = word_of_int (bintrunc n (numeral i))"
  3068   unfolding word_numeral_alt by (rule and_mask_wi)
  3068   unfolding word_numeral_alt by (rule and_mask_wi)
  3069 
  3069 
  3070 lemma bl_and_mask':
  3070 lemma bl_and_mask':
  3071   "to_bl (w AND mask n :: 'a::len word) =
  3071   "to_bl (w AND mask n :: 'a::len word) =
  3072     replicate (len_of TYPE('a) - n) False @
  3072     replicate (LENGTH('a) - n) False @
  3073     drop (len_of TYPE('a) - n) (to_bl w)"
  3073     drop (LENGTH('a) - n) (to_bl w)"
  3074   apply (rule nth_equalityI)
  3074   apply (rule nth_equalityI)
  3075    apply simp
  3075    apply simp
  3076   apply (clarsimp simp add: to_bl_nth word_size)
  3076   apply (clarsimp simp add: to_bl_nth word_size)
  3077   apply (simp add: word_size word_ops_nth_size)
  3077   apply (simp add: word_size word_ops_nth_size)
  3078   apply (auto simp add: word_size test_bit_bl nth_append nth_rev)
  3078   apply (auto simp add: word_size test_bit_bl nth_append nth_rev)
  3176 lemmas revcast_def' = revcast_def [simplified]
  3176 lemmas revcast_def' = revcast_def [simplified]
  3177 lemmas revcast_def'' = revcast_def' [simplified word_size]
  3177 lemmas revcast_def'' = revcast_def' [simplified word_size]
  3178 lemmas revcast_no_def [simp] = revcast_def' [where w="numeral w", unfolded word_size] for w
  3178 lemmas revcast_no_def [simp] = revcast_def' [where w="numeral w", unfolded word_size] for w
  3179 
  3179 
  3180 lemma to_bl_revcast:
  3180 lemma to_bl_revcast:
  3181   "to_bl (revcast w :: 'a::len0 word) = takefill False (len_of TYPE('a)) (to_bl w)"
  3181   "to_bl (revcast w :: 'a::len0 word) = takefill False (LENGTH('a)) (to_bl w)"
  3182   apply (unfold revcast_def' word_size)
  3182   apply (unfold revcast_def' word_size)
  3183   apply (rule word_bl.Abs_inverse)
  3183   apply (rule word_bl.Abs_inverse)
  3184   apply simp
  3184   apply simp
  3185   done
  3185   done
  3186 
  3186 
  3286 
  3286 
  3287 
  3287 
  3288 subsubsection \<open>Slices\<close>
  3288 subsubsection \<open>Slices\<close>
  3289 
  3289 
  3290 lemma slice1_no_bin [simp]:
  3290 lemma slice1_no_bin [simp]:
  3291   "slice1 n (numeral w :: 'b word) = of_bl (takefill False n (bin_to_bl (len_of TYPE('b::len0)) (numeral w)))"
  3291   "slice1 n (numeral w :: 'b word) = of_bl (takefill False n (bin_to_bl (LENGTH('b::len0)) (numeral w)))"
  3292   by (simp add: slice1_def) (* TODO: neg_numeral *)
  3292   by (simp add: slice1_def) (* TODO: neg_numeral *)
  3293 
  3293 
  3294 lemma slice_no_bin [simp]:
  3294 lemma slice_no_bin [simp]:
  3295   "slice n (numeral w :: 'b word) = of_bl (takefill False (len_of TYPE('b::len0) - n)
  3295   "slice n (numeral w :: 'b word) = of_bl (takefill False (LENGTH('b::len0) - n)
  3296     (bin_to_bl (len_of TYPE('b::len0)) (numeral w)))"
  3296     (bin_to_bl (LENGTH('b::len0)) (numeral w)))"
  3297   by (simp add: slice_def word_size) (* TODO: neg_numeral *)
  3297   by (simp add: slice_def word_size) (* TODO: neg_numeral *)
  3298 
  3298 
  3299 lemma slice1_0 [simp] : "slice1 n 0 = 0"
  3299 lemma slice1_0 [simp] : "slice1 n 0 = 0"
  3300   unfolding slice1_def by simp
  3300   unfolding slice1_def by simp
  3301 
  3301 
  3316   apply (unfold slice_take shiftr_bl)
  3316   apply (unfold slice_take shiftr_bl)
  3317   apply (rule ucast_of_bl_up [symmetric])
  3317   apply (rule ucast_of_bl_up [symmetric])
  3318   apply (simp add: word_size)
  3318   apply (simp add: word_size)
  3319   done
  3319   done
  3320 
  3320 
  3321 lemma nth_slice: "(slice n w :: 'a::len0 word) !! m = (w !! (m + n) \<and> m < len_of TYPE('a))"
  3321 lemma nth_slice: "(slice n w :: 'a::len0 word) !! m = (w !! (m + n) \<and> m < LENGTH('a))"
  3322   by (simp add: slice_shiftr nth_ucast nth_shiftr)
  3322   by (simp add: slice_shiftr nth_ucast nth_shiftr)
  3323 
  3323 
  3324 lemma slice1_down_alt':
  3324 lemma slice1_down_alt':
  3325   "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs + k = n \<Longrightarrow>
  3325   "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs + k = n \<Longrightarrow>
  3326     to_bl sl = takefill False fs (drop k (to_bl w))"
  3326     to_bl sl = takefill False fs (drop k (to_bl w))"
  3330 lemma slice1_up_alt':
  3330 lemma slice1_up_alt':
  3331   "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs = n + k \<Longrightarrow>
  3331   "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs = n + k \<Longrightarrow>
  3332     to_bl sl = takefill False fs (replicate k False @ (to_bl w))"
  3332     to_bl sl = takefill False fs (replicate k False @ (to_bl w))"
  3333   apply (unfold slice1_def word_size of_bl_def uint_bl)
  3333   apply (unfold slice1_def word_size of_bl_def uint_bl)
  3334   apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop takefill_append [symmetric])
  3334   apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop takefill_append [symmetric])
  3335   apply (rule_tac f = "\<lambda>k. takefill False (len_of TYPE('a))
  3335   apply (rule_tac f = "\<lambda>k. takefill False (LENGTH('a))
  3336     (replicate k False @ bin_to_bl (len_of TYPE('b)) (uint w))" in arg_cong)
  3336     (replicate k False @ bin_to_bl (LENGTH('b)) (uint w))" in arg_cong)
  3337   apply arith
  3337   apply arith
  3338   done
  3338   done
  3339 
  3339 
  3340 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size]
  3340 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size]
  3341 lemmas su1 = slice1_up_alt' [OF refl refl, unfolded word_size]
  3341 lemmas su1 = slice1_up_alt' [OF refl refl, unfolded word_size]
  3356 lemma revcast_slice1 [OF refl]: "rc = revcast w \<Longrightarrow> slice1 (size rc) w = rc"
  3356 lemma revcast_slice1 [OF refl]: "rc = revcast w \<Longrightarrow> slice1 (size rc) w = rc"
  3357   by (simp add: slice1_def revcast_def' word_size)
  3357   by (simp add: slice1_def revcast_def' word_size)
  3358 
  3358 
  3359 lemma slice1_tf_tf':
  3359 lemma slice1_tf_tf':
  3360   "to_bl (slice1 n w :: 'a::len0 word) =
  3360   "to_bl (slice1 n w :: 'a::len0 word) =
  3361     rev (takefill False (len_of TYPE('a)) (rev (takefill False n (to_bl w))))"
  3361     rev (takefill False (LENGTH('a)) (rev (takefill False n (to_bl w))))"
  3362   unfolding slice1_def by (rule word_rev_tf)
  3362   unfolding slice1_def by (rule word_rev_tf)
  3363 
  3363 
  3364 lemmas slice1_tf_tf = slice1_tf_tf' [THEN word_bl.Rep_inverse', symmetric]
  3364 lemmas slice1_tf_tf = slice1_tf_tf' [THEN word_bl.Rep_inverse', symmetric]
  3365 
  3365 
  3366 lemma rev_slice1:
  3366 lemma rev_slice1:
  3367   "n + k = len_of TYPE('a) + len_of TYPE('b) \<Longrightarrow>
  3367   "n + k = LENGTH('a) + LENGTH('b) \<Longrightarrow>
  3368     slice1 n (word_reverse w :: 'b::len0 word) =
  3368     slice1 n (word_reverse w :: 'b::len0 word) =
  3369     word_reverse (slice1 k w :: 'a::len0 word)"
  3369     word_reverse (slice1 k w :: 'a::len0 word)"
  3370   apply (unfold word_reverse_def slice1_tf_tf)
  3370   apply (unfold word_reverse_def slice1_tf_tf)
  3371   apply (rule word_bl.Rep_inverse')
  3371   apply (rule word_bl.Rep_inverse')
  3372   apply (rule rev_swap [THEN iffD1])
  3372   apply (rule rev_swap [THEN iffD1])
  3375    apply (simp add: word_bl.Abs_inverse)
  3375    apply (simp add: word_bl.Abs_inverse)
  3376   apply (simp add: word_bl.Abs_inverse)
  3376   apply (simp add: word_bl.Abs_inverse)
  3377   done
  3377   done
  3378 
  3378 
  3379 lemma rev_slice:
  3379 lemma rev_slice:
  3380   "n + k + len_of TYPE('a::len0) = len_of TYPE('b::len0) \<Longrightarrow>
  3380   "n + k + LENGTH('a::len0) = LENGTH('b::len0) \<Longrightarrow>
  3381     slice n (word_reverse (w::'b word)) = word_reverse (slice k w :: 'a word)"
  3381     slice n (word_reverse (w::'b word)) = word_reverse (slice k w :: 'a word)"
  3382   apply (unfold slice_def word_size)
  3382   apply (unfold slice_def word_size)
  3383   apply (rule rev_slice1)
  3383   apply (rule rev_slice1)
  3384   apply arith
  3384   apply arith
  3385   done
  3385   done
  3393 lemma sofl_test:
  3393 lemma sofl_test:
  3394   "(sint x + sint y = sint (x + y)) =
  3394   "(sint x + sint y = sint (x + y)) =
  3395      ((((x + y) XOR x) AND ((x + y) XOR y)) >> (size x - 1) = 0)"
  3395      ((((x + y) XOR x) AND ((x + y) XOR y)) >> (size x - 1) = 0)"
  3396   for x y :: "'a::len word"
  3396   for x y :: "'a::len word"
  3397   apply (unfold word_size)
  3397   apply (unfold word_size)
  3398   apply (cases "len_of TYPE('a)", simp)
  3398   apply (cases "LENGTH('a)", simp)
  3399   apply (subst msb_shift [THEN sym_notr])
  3399   apply (subst msb_shift [THEN sym_notr])
  3400   apply (simp add: word_ops_msb)
  3400   apply (simp add: word_ops_msb)
  3401   apply (simp add: word_msb_sint)
  3401   apply (simp add: word_msb_sint)
  3402   apply safe
  3402   apply safe
  3403        apply simp_all
  3403        apply simp_all
  3429 lemmas word_split_bin' = word_split_def
  3429 lemmas word_split_bin' = word_split_def
  3430 lemmas word_cat_bin' = word_cat_def
  3430 lemmas word_cat_bin' = word_cat_def
  3431 
  3431 
  3432 lemma word_rsplit_no:
  3432 lemma word_rsplit_no:
  3433   "(word_rsplit (numeral bin :: 'b::len0 word) :: 'a word list) =
  3433   "(word_rsplit (numeral bin :: 'b::len0 word) :: 'a word list) =
  3434     map word_of_int (bin_rsplit (len_of TYPE('a::len))
  3434     map word_of_int (bin_rsplit (LENGTH('a::len))
  3435       (len_of TYPE('b), bintrunc (len_of TYPE('b)) (numeral bin)))"
  3435       (LENGTH('b), bintrunc (LENGTH('b)) (numeral bin)))"
  3436   by (simp add: word_rsplit_def word_ubin.eq_norm)
  3436   by (simp add: word_rsplit_def word_ubin.eq_norm)
  3437 
  3437 
  3438 lemmas word_rsplit_no_cl [simp] = word_rsplit_no
  3438 lemmas word_rsplit_no_cl [simp] = word_rsplit_no
  3439   [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]]
  3439   [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]]
  3440 
  3440 
  3462 
  3462 
  3463 lemma of_bl_Cons: "of_bl (x#xs) = of_bool x * 2^length xs + of_bl xs"
  3463 lemma of_bl_Cons: "of_bl (x#xs) = of_bool x * 2^length xs + of_bl xs"
  3464   by (cases x) simp_all
  3464   by (cases x) simp_all
  3465 
  3465 
  3466 lemma split_uint_lem: "bin_split n (uint w) = (a, b) \<Longrightarrow>
  3466 lemma split_uint_lem: "bin_split n (uint w) = (a, b) \<Longrightarrow>
  3467     a = bintrunc (len_of TYPE('a) - n) a \<and> b = bintrunc (len_of TYPE('a)) b"
  3467     a = bintrunc (LENGTH('a) - n) a \<and> b = bintrunc (LENGTH('a)) b"
  3468   for w :: "'a::len0 word"
  3468   for w :: "'a::len0 word"
  3469   apply (frule word_ubin.norm_Rep [THEN ssubst])
  3469   apply (frule word_ubin.norm_Rep [THEN ssubst])
  3470   apply (drule bin_split_trunc1)
  3470   apply (drule bin_split_trunc1)
  3471   apply (drule sym [THEN trans])
  3471   apply (drule sym [THEN trans])
  3472    apply assumption
  3472    apply assumption
  3486    apply (simp add: of_bl_def bl2bin_drop word_size
  3486    apply (simp add: of_bl_def bl2bin_drop word_size
  3487       word_ubin.norm_eq_iff [symmetric] min_def del: word_ubin.norm_Rep)
  3487       word_ubin.norm_eq_iff [symmetric] min_def del: word_ubin.norm_Rep)
  3488   apply (clarsimp split: prod.splits)
  3488   apply (clarsimp split: prod.splits)
  3489   apply (frule split_uint_lem [THEN conjunct1])
  3489   apply (frule split_uint_lem [THEN conjunct1])
  3490   apply (unfold word_size)
  3490   apply (unfold word_size)
  3491   apply (cases "len_of TYPE('a) \<ge> len_of TYPE('b)")
  3491   apply (cases "LENGTH('a) \<ge> LENGTH('b)")
  3492    defer
  3492    defer
  3493    apply simp
  3493    apply simp
  3494   apply (simp add : of_bl_def to_bl_def)
  3494   apply (simp add : of_bl_def to_bl_def)
  3495   apply (subst bin_split_take1 [symmetric])
  3495   apply (subst bin_split_take1 [symmetric])
  3496     prefer 2
  3496     prefer 2
  3513    apply (auto simp add: word_size)
  3513    apply (auto simp add: word_size)
  3514   done
  3514   done
  3515 
  3515 
  3516 lemma word_split_bl_eq:
  3516 lemma word_split_bl_eq:
  3517   "(word_split c :: ('c::len0 word \<times> 'd::len0 word)) =
  3517   "(word_split c :: ('c::len0 word \<times> 'd::len0 word)) =
  3518     (of_bl (take (len_of TYPE('a::len) - len_of TYPE('d::len0)) (to_bl c)),
  3518     (of_bl (take (LENGTH('a::len) - LENGTH('d::len0)) (to_bl c)),
  3519      of_bl (drop (len_of TYPE('a) - len_of TYPE('d)) (to_bl c)))"
  3519      of_bl (drop (LENGTH('a) - LENGTH('d)) (to_bl c)))"
  3520   for c :: "'a::len word"
  3520   for c :: "'a::len word"
  3521   apply (rule word_split_bl [THEN iffD1])
  3521   apply (rule word_split_bl [THEN iffD1])
  3522    apply (unfold word_size)
  3522    apply (unfold word_size)
  3523    apply (rule refl conjI)+
  3523    apply (rule refl conjI)+
  3524   done
  3524   done
  3564 lemma word_cat_id: "word_cat a b = b"
  3564 lemma word_cat_id: "word_cat a b = b"
  3565   by (simp add: word_cat_bin' word_ubin.inverse_norm)
  3565   by (simp add: word_cat_bin' word_ubin.inverse_norm)
  3566 
  3566 
  3567 \<comment> \<open>limited hom result\<close>
  3567 \<comment> \<open>limited hom result\<close>
  3568 lemma word_cat_hom:
  3568 lemma word_cat_hom:
  3569   "len_of TYPE('a::len0) \<le> len_of TYPE('b::len0) + len_of TYPE('c::len0) \<Longrightarrow>
  3569   "LENGTH('a::len0) \<le> LENGTH('b::len0) + LENGTH('c::len0) \<Longrightarrow>
  3570     (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) =
  3570     (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) =
  3571     word_of_int (bin_cat w (size b) (uint b))"
  3571     word_of_int (bin_cat w (size b) (uint b))"
  3572   by (auto simp: word_cat_def word_size word_ubin.norm_eq_iff [symmetric]
  3572   by (auto simp: word_cat_def word_size word_ubin.norm_eq_iff [symmetric]
  3573       word_ubin.eq_norm bintr_cat min.absorb1)
  3573       word_ubin.eq_norm bintr_cat min.absorb1)
  3574 
  3574 
  3667 lemmas size_rcat_lem = size_rcat_lem' [unfolded word_size]
  3667 lemmas size_rcat_lem = size_rcat_lem' [unfolded word_size]
  3668 
  3668 
  3669 lemmas td_gal_lt_len = len_gt_0 [THEN td_gal_lt]
  3669 lemmas td_gal_lt_len = len_gt_0 [THEN td_gal_lt]
  3670 
  3670 
  3671 lemma nth_rcat_lem:
  3671 lemma nth_rcat_lem:
  3672   "n < length (wl::'a word list) * len_of TYPE('a::len) \<Longrightarrow>
  3672   "n < length (wl::'a word list) * LENGTH('a::len) \<Longrightarrow>
  3673     rev (concat (map to_bl wl)) ! n =
  3673     rev (concat (map to_bl wl)) ! n =
  3674     rev (to_bl (rev wl ! (n div len_of TYPE('a)))) ! (n mod len_of TYPE('a))"
  3674     rev (to_bl (rev wl ! (n div LENGTH('a)))) ! (n mod LENGTH('a))"
  3675   apply (induct wl)
  3675   apply (induct wl)
  3676    apply clarsimp
  3676    apply clarsimp
  3677   apply (clarsimp simp add : nth_append size_rcat_lem)
  3677   apply (clarsimp simp add : nth_append size_rcat_lem)
  3678   apply (simp (no_asm_use) only:  mult_Suc [symmetric]
  3678   apply (simp (no_asm_use) only:  mult_Suc [symmetric]
  3679          td_gal_lt_len less_Suc_eq_le minus_div_mult_eq_mod [symmetric])
  3679          td_gal_lt_len less_Suc_eq_le minus_div_mult_eq_mod [symmetric])
  3705   "[u,v] = p \<Longrightarrow> [su,sv] = q \<Longrightarrow> word_rsplit u = su \<Longrightarrow>
  3705   "[u,v] = p \<Longrightarrow> [su,sv] = q \<Longrightarrow> word_rsplit u = su \<Longrightarrow>
  3706     word_rsplit v = sv \<Longrightarrow> length su = length sv"
  3706     word_rsplit v = sv \<Longrightarrow> length su = length sv"
  3707   by (auto simp: word_rsplit_def bin_rsplit_len_indep)
  3707   by (auto simp: word_rsplit_def bin_rsplit_len_indep)
  3708 
  3708 
  3709 lemma length_word_rsplit_size:
  3709 lemma length_word_rsplit_size:
  3710   "n = len_of TYPE('a::len) \<Longrightarrow>
  3710   "n = LENGTH('a::len) \<Longrightarrow>
  3711     length (word_rsplit w :: 'a word list) \<le> m \<longleftrightarrow> size w \<le> m * n"
  3711     length (word_rsplit w :: 'a word list) \<le> m \<longleftrightarrow> size w \<le> m * n"
  3712   by (auto simp: word_rsplit_def word_size bin_rsplit_len_le)
  3712   by (auto simp: word_rsplit_def word_size bin_rsplit_len_le)
  3713 
  3713 
  3714 lemmas length_word_rsplit_lt_size =
  3714 lemmas length_word_rsplit_lt_size =
  3715   length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]]
  3715   length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]]
  3716 
  3716 
  3717 lemma length_word_rsplit_exp_size:
  3717 lemma length_word_rsplit_exp_size:
  3718   "n = len_of TYPE('a::len) \<Longrightarrow>
  3718   "n = LENGTH('a::len) \<Longrightarrow>
  3719     length (word_rsplit w :: 'a word list) = (size w + n - 1) div n"
  3719     length (word_rsplit w :: 'a word list) = (size w + n - 1) div n"
  3720   by (auto simp: word_rsplit_def word_size bin_rsplit_len)
  3720   by (auto simp: word_rsplit_def word_size bin_rsplit_len)
  3721 
  3721 
  3722 lemma length_word_rsplit_even_size:
  3722 lemma length_word_rsplit_even_size:
  3723   "n = len_of TYPE('a::len) \<Longrightarrow> size w = m * n \<Longrightarrow>
  3723   "n = LENGTH('a::len) \<Longrightarrow> size w = m * n \<Longrightarrow>
  3724     length (word_rsplit w :: 'a word list) = m"
  3724     length (word_rsplit w :: 'a word list) = m"
  3725   by (auto simp: length_word_rsplit_exp_size given_quot_alt)
  3725   by (auto simp: length_word_rsplit_exp_size given_quot_alt)
  3726 
  3726 
  3727 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size]
  3727 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size]
  3728 
  3728 
  3739    apply safe
  3739    apply safe
  3740    apply (erule xtr7, rule dtle)+
  3740    apply (erule xtr7, rule dtle)+
  3741   done
  3741   done
  3742 
  3742 
  3743 lemma size_word_rsplit_rcat_size:
  3743 lemma size_word_rsplit_rcat_size:
  3744   "word_rcat ws = frcw \<Longrightarrow> size frcw = length ws * len_of TYPE('a)
  3744   "word_rcat ws = frcw \<Longrightarrow> size frcw = length ws * LENGTH('a)
  3745     \<Longrightarrow> length (word_rsplit frcw::'a word list) = length ws"
  3745     \<Longrightarrow> length (word_rsplit frcw::'a word list) = length ws"
  3746   for ws :: "'a::len word list" and frcw :: "'b::len0 word"
  3746   for ws :: "'a::len word list" and frcw :: "'b::len0 word"
  3747   apply (clarsimp simp: word_size length_word_rsplit_exp_size')
  3747   apply (clarsimp simp: word_size length_word_rsplit_exp_size')
  3748   apply (fast intro: given_quot_alt)
  3748   apply (fast intro: given_quot_alt)
  3749   done
  3749   done
  3754   for n :: nat
  3754   for n :: nat
  3755   by (auto simp: add.commute)
  3755   by (auto simp: add.commute)
  3756 
  3756 
  3757 lemma word_rsplit_rcat_size [OF refl]:
  3757 lemma word_rsplit_rcat_size [OF refl]:
  3758   "word_rcat ws = frcw \<Longrightarrow>
  3758   "word_rcat ws = frcw \<Longrightarrow>
  3759     size frcw = length ws * len_of TYPE('a) \<Longrightarrow> word_rsplit frcw = ws"
  3759     size frcw = length ws * LENGTH('a) \<Longrightarrow> word_rsplit frcw = ws"
  3760   for ws :: "'a::len word list"
  3760   for ws :: "'a::len word list"
  3761   apply (frule size_word_rsplit_rcat_size, assumption)
  3761   apply (frule size_word_rsplit_rcat_size, assumption)
  3762   apply (clarsimp simp add : word_size)
  3762   apply (clarsimp simp add : word_size)
  3763   apply (rule nth_equalityI, assumption)
  3763   apply (rule nth_equalityI, assumption)
  3764   apply clarsimp
  3764   apply clarsimp
  4134 
  4134 
  4135 subsection \<open>Maximum machine word\<close>
  4135 subsection \<open>Maximum machine word\<close>
  4136 
  4136 
  4137 lemma word_int_cases:
  4137 lemma word_int_cases:
  4138   fixes x :: "'a::len0 word"
  4138   fixes x :: "'a::len0 word"
  4139   obtains n where "x = word_of_int n" and "0 \<le> n" and "n < 2^len_of TYPE('a)"
  4139   obtains n where "x = word_of_int n" and "0 \<le> n" and "n < 2^LENGTH('a)"
  4140   by (cases x rule: word_uint.Abs_cases) (simp add: uints_num)
  4140   by (cases x rule: word_uint.Abs_cases) (simp add: uints_num)
  4141 
  4141 
  4142 lemma word_nat_cases [cases type: word]:
  4142 lemma word_nat_cases [cases type: word]:
  4143   fixes x :: "'a::len word"
  4143   fixes x :: "'a::len word"
  4144   obtains n where "x = of_nat n" and "n < 2^len_of TYPE('a)"
  4144   obtains n where "x = of_nat n" and "n < 2^LENGTH('a)"
  4145   by (cases x rule: word_unat.Abs_cases) (simp add: unats_def)
  4145   by (cases x rule: word_unat.Abs_cases) (simp add: unats_def)
  4146 
  4146 
  4147 lemma max_word_eq: "(max_word::'a::len word) = 2^len_of TYPE('a) - 1"
  4147 lemma max_word_eq: "(max_word::'a::len word) = 2^LENGTH('a) - 1"
  4148   by (simp add: max_word_def word_of_int_hom_syms word_of_int_2p)
  4148   by (simp add: max_word_def word_of_int_hom_syms word_of_int_2p)
  4149 
  4149 
  4150 lemma max_word_max [simp,intro!]: "n \<le> max_word"
  4150 lemma max_word_max [simp,intro!]: "n \<le> max_word"
  4151   by (cases n rule: word_int_cases)
  4151   by (cases n rule: word_int_cases)
  4152     (simp add: max_word_def word_le_def int_word_uint mod_pos_pos_trivial del: minus_mod_self1)
  4152     (simp add: max_word_def word_le_def int_word_uint mod_pos_pos_trivial del: minus_mod_self1)
  4153 
  4153 
  4154 lemma word_of_int_2p_len: "word_of_int (2 ^ len_of TYPE('a)) = (0::'a::len0 word)"
  4154 lemma word_of_int_2p_len: "word_of_int (2 ^ LENGTH('a)) = (0::'a::len0 word)"
  4155   by (subst word_uint.Abs_norm [symmetric]) simp
  4155   by (subst word_uint.Abs_norm [symmetric]) simp
  4156 
  4156 
  4157 lemma word_pow_0: "(2::'a::len word) ^ len_of TYPE('a) = 0"
  4157 lemma word_pow_0: "(2::'a::len word) ^ LENGTH('a) = 0"
  4158 proof -
  4158 proof -
  4159   have "word_of_int (2 ^ len_of TYPE('a)) = (0::'a word)"
  4159   have "word_of_int (2 ^ LENGTH('a)) = (0::'a word)"
  4160     by (rule word_of_int_2p_len)
  4160     by (rule word_of_int_2p_len)
  4161   then show ?thesis by (simp add: word_of_int_2p)
  4161   then show ?thesis by (simp add: word_of_int_2p)
  4162 qed
  4162 qed
  4163 
  4163 
  4164 lemma max_word_wrap: "x + 1 = 0 \<Longrightarrow> x = max_word"
  4164 lemma max_word_wrap: "x + 1 = 0 \<Longrightarrow> x = max_word"
  4173     by simp
  4173     by simp
  4174   then show ?thesis
  4174   then show ?thesis
  4175     by (rule max_word_wrap [symmetric])
  4175     by (rule max_word_wrap [symmetric])
  4176 qed
  4176 qed
  4177 
  4177 
  4178 lemma max_word_bl [simp]: "to_bl (max_word::'a::len word) = replicate (len_of TYPE('a)) True"
  4178 lemma max_word_bl [simp]: "to_bl (max_word::'a::len word) = replicate (LENGTH('a)) True"
  4179   by (subst max_word_minus to_bl_n1)+ simp
  4179   by (subst max_word_minus to_bl_n1)+ simp
  4180 
  4180 
  4181 lemma max_test_bit [simp]: "(max_word::'a::len word) !! n \<longleftrightarrow> n < len_of TYPE('a)"
  4181 lemma max_test_bit [simp]: "(max_word::'a::len word) !! n \<longleftrightarrow> n < LENGTH('a)"
  4182   by (auto simp: test_bit_bl word_size)
  4182   by (auto simp: test_bit_bl word_size)
  4183 
  4183 
  4184 lemma word_and_max [simp]: "x AND max_word = x"
  4184 lemma word_and_max [simp]: "x AND max_word = x"
  4185   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
  4185   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
  4186 
  4186 
  4254   for x :: "'a::len word"
  4254   for x :: "'a::len word"
  4255   by (simp add: word_less_nat_alt unat_0_iff)
  4255   by (simp add: word_less_nat_alt unat_0_iff)
  4256 
  4256 
  4257 lemma to_bl_mask:
  4257 lemma to_bl_mask:
  4258   "to_bl (mask n :: 'a::len word) =
  4258   "to_bl (mask n :: 'a::len word) =
  4259   replicate (len_of TYPE('a) - n) False @
  4259   replicate (LENGTH('a) - n) False @
  4260     replicate (min (len_of TYPE('a)) n) True"
  4260     replicate (min (LENGTH('a)) n) True"
  4261   by (simp add: mask_bl word_rep_drop min_def)
  4261   by (simp add: mask_bl word_rep_drop min_def)
  4262 
  4262 
  4263 lemma map_replicate_True:
  4263 lemma map_replicate_True:
  4264   "n = length xs \<Longrightarrow>
  4264   "n = length xs \<Longrightarrow>
  4265     map (\<lambda>(x,y). x \<and> y) (zip xs (replicate n True)) = xs"
  4265     map (\<lambda>(x,y). x \<and> y) (zip xs (replicate n True)) = xs"
  4271   by (induct xs arbitrary: n) auto
  4271   by (induct xs arbitrary: n) auto
  4272 
  4272 
  4273 lemma bl_and_mask:
  4273 lemma bl_and_mask:
  4274   fixes w :: "'a::len word"
  4274   fixes w :: "'a::len word"
  4275     and n :: nat
  4275     and n :: nat
  4276   defines "n' \<equiv> len_of TYPE('a) - n"
  4276   defines "n' \<equiv> LENGTH('a) - n"
  4277   shows "to_bl (w AND mask n) = replicate n' False @ drop n' (to_bl w)"
  4277   shows "to_bl (w AND mask n) = replicate n' False @ drop n' (to_bl w)"
  4278 proof -
  4278 proof -
  4279   note [simp] = map_replicate_True map_replicate_False
  4279   note [simp] = map_replicate_True map_replicate_False
  4280   have "to_bl (w AND mask n) = map2 (\<and>) (to_bl w) (to_bl (mask n::'a::len word))"
  4280   have "to_bl (w AND mask n) = map2 (\<and>) (to_bl w) (to_bl (mask n::'a::len word))"
  4281     by (simp add: bl_word_and)
  4281     by (simp add: bl_word_and)
  4332   by (simp add: unat_def uint_sub_if_size word_le_def nat_diff_distrib)
  4332   by (simp add: unat_def uint_sub_if_size word_le_def nat_diff_distrib)
  4333 
  4333 
  4334 lemmas word_less_sub1_numberof [simp] = word_less_sub1 [of "numeral w"] for w
  4334 lemmas word_less_sub1_numberof [simp] = word_less_sub1 [of "numeral w"] for w
  4335 lemmas word_le_sub1_numberof [simp] = word_le_sub1 [of "numeral w"] for w
  4335 lemmas word_le_sub1_numberof [simp] = word_le_sub1 [of "numeral w"] for w
  4336 
  4336 
  4337 lemma word_of_int_minus: "word_of_int (2^len_of TYPE('a) - i) = (word_of_int (-i)::'a::len word)"
  4337 lemma word_of_int_minus: "word_of_int (2^LENGTH('a) - i) = (word_of_int (-i)::'a::len word)"
  4338 proof -
  4338 proof -
  4339   have *: "2^len_of TYPE('a) - i = -i + 2^len_of TYPE('a)"
  4339   have *: "2^LENGTH('a) - i = -i + 2^LENGTH('a)"
  4340     by simp
  4340     by simp
  4341   show ?thesis
  4341   show ?thesis
  4342     apply (subst *)
  4342     apply (subst *)
  4343     apply (subst word_uint.Abs_norm [symmetric], subst mod_add_self2)
  4343     apply (subst word_uint.Abs_norm [symmetric], subst mod_add_self2)
  4344     apply simp
  4344     apply simp
  4511 lemma set_bits_K_False [simp]:
  4511 lemma set_bits_K_False [simp]:
  4512   "set_bits (\<lambda>_. False) = (0 :: 'a :: len0 word)"
  4512   "set_bits (\<lambda>_. False) = (0 :: 'a :: len0 word)"
  4513   by (rule word_eqI) (simp add: test_bit.eq_norm)
  4513   by (rule word_eqI) (simp add: test_bit.eq_norm)
  4514 
  4514 
  4515 lemma test_bit_1' [simp]:
  4515 lemma test_bit_1' [simp]:
  4516   "(1 :: 'a :: len0 word) !! n \<longleftrightarrow> 0 < len_of TYPE('a) \<and> n = 0"
  4516   "(1 :: 'a :: len0 word) !! n \<longleftrightarrow> 0 < LENGTH('a) \<and> n = 0"
  4517   by (cases n) (simp_all only: one_word_def test_bit_wi bin_nth.simps, simp_all)
  4517   by (cases n) (simp_all only: one_word_def test_bit_wi bin_nth.simps, simp_all)
  4518 
  4518 
  4519 lemma mask_0 [simp]:
  4519 lemma mask_0 [simp]:
  4520   "mask 0 = 0"
  4520   "mask 0 = 0"
  4521   by (simp add: Word.mask_def)
  4521   by (simp add: Word.mask_def)