src/HOL/Word/WordArith.thy
changeset 24408 058c5613a86f
parent 24397 eaf37b780683
child 24415 640b85390ba0
equal deleted inserted replaced
24407:61b10ffb2549 24408:058c5613a86f
    27 
    27 
    28 lemma int_one_bin: "(1 :: int) == (Numeral.Pls BIT bit.B1)"
    28 lemma int_one_bin: "(1 :: int) == (Numeral.Pls BIT bit.B1)"
    29   unfolding Pls_def Bit_def by auto
    29   unfolding Pls_def Bit_def by auto
    30 
    30 
    31 lemma word_1_no: 
    31 lemma word_1_no: 
    32   "(1 :: 'a :: len0 word) == number_of (Numeral.Pls BIT bit.B1)"
    32   "(1 :: 'a word) == number_of (Numeral.Pls BIT bit.B1)"
    33   unfolding word_1_wi word_number_of_def int_one_bin by auto
    33   unfolding word_1_wi word_number_of_def int_one_bin by auto
    34 
    34 
    35 lemma word_m1_wi: "-1 == word_of_int -1" 
    35 lemma word_m1_wi: "-1 == word_of_int -1" 
    36   by (rule word_number_of_alt)
    36   by (rule word_number_of_alt)
    37 
    37 
    49   unfolding unat_def by (auto simp add : nat_eq_iff uint_0_iff)
    49   unfolding unat_def by (auto simp add : nat_eq_iff uint_0_iff)
    50 
    50 
    51 lemma unat_0 [simp]: "unat 0 = 0"
    51 lemma unat_0 [simp]: "unat 0 = 0"
    52   unfolding unat_def by auto
    52   unfolding unat_def by auto
    53 
    53 
    54 lemma size_0_same': "size w = 0 ==> w = (v :: 'a :: len0 word)"
    54 lemma size_0_same': "size w = 0 ==> w = (v :: 'a word)"
    55   apply (unfold word_size)
    55   apply (unfold word_size)
    56   apply (rule box_equals)
    56   apply (rule box_equals)
    57     defer
    57     defer
    58     apply (rule word_uint.Rep_inverse)+
    58     apply (rule word_uint.Rep_inverse)+
    59   apply (rule word_ubin.norm_eq_iff [THEN iffD1])
    59   apply (rule word_ubin.norm_eq_iff [THEN iffD1])
    93   apply (unfold scast_def sint_n1)
    93   apply (unfold scast_def sint_n1)
    94   apply (unfold word_number_of_alt)
    94   apply (unfold word_number_of_alt)
    95   apply (rule refl)
    95   apply (rule refl)
    96   done
    96   done
    97 
    97 
    98 lemma uint_1 [simp] : "uint (1 :: 'a :: len word) = 1"
    98 lemma uint_1 [simp] : "uint (1 :: 'a :: finite word) = 1"
    99   unfolding word_1_wi
    99   unfolding word_1_wi
   100   by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps)
   100   by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps)
   101 
   101 
   102 lemma unat_1 [simp] : "unat (1 :: 'a :: len word) = 1"
   102 lemma unat_1 [simp] : "unat (1 :: 'a :: finite word) = 1"
   103   by (unfold unat_def uint_1) auto
   103   by (unfold unat_def uint_1) auto
   104 
   104 
   105 lemma ucast_1 [simp] : "ucast (1 :: 'a :: len word) = 1"
   105 lemma ucast_1 [simp] : "ucast (1 :: 'a :: finite word) = 1"
   106   unfolding ucast_def word_1_wi
   106   unfolding ucast_def word_1_wi
   107   by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps)
   107   by (simp add: word_ubin.eq_norm int_one_bin bintrunc_minus_simps)
   108 
   108 
   109 (* abstraction preserves the operations
   109 (* abstraction preserves the operations
   110   (the definitions tell this for bins in range uint) *)
   110   (the definitions tell this for bins in range uint) *)
   122   wi_hom_pred: "word_pred (word_of_int a) = word_of_int (Numeral.pred a)"
   122   wi_hom_pred: "word_pred (word_of_int a) = word_of_int (Numeral.pred a)"
   123   by (auto simp: word_arith_wis arths)
   123   by (auto simp: word_arith_wis arths)
   124 
   124 
   125 lemmas wi_hom_syms = wi_homs [symmetric]
   125 lemmas wi_hom_syms = wi_homs [symmetric]
   126 
   126 
   127 lemma word_sub_def: "a - b == a + - (b :: 'a :: len0 word)"
   127 lemma word_sub_def: "a - b == a + - (b :: 'a word)"
   128   unfolding word_sub_wi diff_def
   128   unfolding word_sub_wi diff_def
   129   by (simp only : word_uint.Rep_inverse wi_hom_syms)
   129   by (simp only : word_uint.Rep_inverse wi_hom_syms)
   130     
   130     
   131 lemmas word_diff_minus = word_sub_def [THEN meta_eq_to_obj_eq, standard]
   131 lemmas word_diff_minus = word_sub_def [THEN meta_eq_to_obj_eq, standard]
   132 
   132 
   191 
   191 
   192 (* similar expressions for sint (arith operations) *)
   192 (* similar expressions for sint (arith operations) *)
   193 lemmas sint_word_ariths = uint_word_arith_bintrs
   193 lemmas sint_word_ariths = uint_word_arith_bintrs
   194   [THEN uint_sint [symmetric, THEN trans],
   194   [THEN uint_sint [symmetric, THEN trans],
   195   unfolded uint_sint bintr_arith1s bintr_ariths 
   195   unfolded uint_sint bintr_arith1s bintr_ariths 
   196     len_gt_0 [THEN bin_sbin_eq_iff'] word_sbin.norm_Rep, standard]
   196     zero_less_card_finite [THEN bin_sbin_eq_iff'] word_sbin.norm_Rep, standard]
   197 
   197 
   198 lemma word_pred_0_n1: "word_pred 0 = word_of_int -1"
   198 lemma word_pred_0_n1: "word_pred 0 = word_of_int -1"
   199   unfolding word_pred_def number_of_eq
   199   unfolding word_pred_def number_of_eq
   200   by (simp add : pred_def word_no_wi)
   200   by (simp add : pred_def word_no_wi)
   201 
   201 
   218 lemma word_of_int_Ex:
   218 lemma word_of_int_Ex:
   219   "\<exists>y. x = word_of_int y"
   219   "\<exists>y. x = word_of_int y"
   220   by (rule_tac x="uint x" in exI) simp
   220   by (rule_tac x="uint x" in exI) simp
   221 
   221 
   222 lemma word_arith_eqs:
   222 lemma word_arith_eqs:
   223   fixes a :: "'a::len0 word"
   223   fixes a :: "'a word"
   224   fixes b :: "'a::len0 word"
   224   fixes b :: "'a word"
   225   shows
   225   shows
   226   word_add_0: "0 + a = a" and
   226   word_add_0: "0 + a = a" and
   227   word_add_0_right: "a + 0 = a" and
   227   word_add_0_right: "a + 0 = a" and
   228   word_mult_1: "1 * a = a" and
   228   word_mult_1: "1 * a = a" and
   229   word_mult_1_right: "a * 1 = a" and
   229   word_mult_1_right: "a * 1 = a" and
   250 lemmas word_mult_ac = word_mult_commute word_mult_assoc word_mult_left_commute
   250 lemmas word_mult_ac = word_mult_commute word_mult_assoc word_mult_left_commute
   251   
   251   
   252 lemmas word_plus_ac0 = word_add_0 word_add_0_right word_add_ac
   252 lemmas word_plus_ac0 = word_add_0 word_add_0_right word_add_ac
   253 lemmas word_times_ac1 = word_mult_1 word_mult_1_right word_mult_ac
   253 lemmas word_times_ac1 = word_mult_1 word_mult_1_right word_mult_ac
   254 
   254 
   255 instance word :: (len0) semigroup_add
   255 instance word :: (type) semigroup_add
   256   by intro_classes (simp add: word_add_assoc)
   256   by intro_classes (simp add: word_add_assoc)
   257 
   257 
   258 instance word :: (len0) ring
   258 instance word :: (type) ring
   259   by intro_classes
   259   by intro_classes
   260      (auto simp: word_arith_eqs word_diff_minus 
   260      (auto simp: word_arith_eqs word_diff_minus 
   261                  word_diff_self [unfolded word_diff_minus])
   261                  word_diff_self [unfolded word_diff_minus])
   262 
   262 
   263 
   263 
   264 subsection "Order on fixed-length words"
   264 subsection "Order on fixed-length words"
   265 
   265 
   266 instance word :: (len0) ord
   266 instance word :: (type) ord
   267   word_le_def: "a <= b == uint a <= uint b"
   267   word_le_def: "a <= b == uint a <= uint b"
   268   word_less_def: "x < y == x <= y & x ~= y"
   268   word_less_def: "x < y == x <= y & x ~= y"
   269   ..
   269   ..
   270 
   270 
   271 constdefs
   271 constdefs
   272   word_sle :: "'a :: len word => 'a word => bool" ("(_/ <=s _)" [50, 51] 50)
   272   word_sle :: "'a :: finite word => 'a word => bool" ("(_/ <=s _)" [50, 51] 50)
   273   "a <=s b == sint a <= sint b"
   273   "a <=s b == sint a <= sint b"
   274 
   274 
   275   word_sless :: "'a :: len word => 'a word => bool" ("(_/ <s _)" [50, 51] 50)
   275   word_sless :: "'a :: finite word => 'a word => bool" ("(_/ <s _)" [50, 51] 50)
   276   "(x <s y) == (x <=s y & x ~= y)"
   276   "(x <s y) == (x <=s y & x ~= y)"
   277 
   277 
   278 lemma word_less_alt: "(a < b) = (uint a < uint b)"
   278 lemma word_less_alt: "(a < b) = (uint a < uint b)"
   279   unfolding word_less_def word_le_def
   279   unfolding word_less_def word_le_def
   280   by (auto simp del: word_uint.Rep_inject 
   280   by (auto simp del: word_uint.Rep_inject 
   298   word_sless_def [of "number_of ?a" "number_of ?b"]
   298   word_sless_def [of "number_of ?a" "number_of ?b"]
   299 
   299 
   300 lemmas word_sle_no [simp] = 
   300 lemmas word_sle_no [simp] = 
   301   word_sle_def [of "number_of ?a" "number_of ?b"]
   301   word_sle_def [of "number_of ?a" "number_of ?b"]
   302 
   302 
   303 lemma word_order_trans: "x <= y ==> y <= z ==> x <= (z :: 'a :: len0 word)"
   303 lemma word_order_trans: "x <= y ==> y <= z ==> x <= (z :: 'a word)"
   304   unfolding word_le_def by auto
   304   unfolding word_le_def by auto
   305 
   305 
   306 lemma word_order_refl: "z <= (z :: 'a :: len0 word)"
   306 lemma word_order_refl: "z <= (z :: 'a word)"
   307   unfolding word_le_def by auto
   307   unfolding word_le_def by auto
   308 
   308 
   309 lemma word_order_antisym: "x <= y ==> y <= x ==> x = (y :: 'a :: len0 word)"
   309 lemma word_order_antisym: "x <= y ==> y <= x ==> x = (y :: 'a word)"
   310   unfolding word_le_def by (auto intro!: word_uint.Rep_eqD)
   310   unfolding word_le_def by (auto intro!: word_uint.Rep_eqD)
   311 
   311 
   312 lemma word_order_linear:
   312 lemma word_order_linear:
   313   "y <= x | x <= (y :: 'a :: len0 word)"
   313   "y <= x | x <= (y :: 'a word)"
   314   unfolding word_le_def by auto
   314   unfolding word_le_def by auto
   315 
   315 
   316 lemma word_zero_le [simp] :
   316 lemma word_zero_le [simp] :
   317   "0 <= (y :: 'a :: len0 word)"
   317   "0 <= (y :: 'a word)"
   318   unfolding word_le_def by auto
   318   unfolding word_le_def by auto
   319 
   319 
   320 instance word :: (len0) linorder
   320 instance word :: (type) linorder
   321   by intro_classes (auto simp: word_less_def word_le_def)
   321   by intro_classes (auto simp: word_less_def word_le_def)
   322 
   322 
   323 lemma word_m1_ge [simp] : "word_pred 0 >= y"
   323 lemma word_m1_ge [simp] : "word_pred 0 >= y"
   324   unfolding word_le_def
   324   unfolding word_le_def
   325   by (simp only : word_pred_0_n1 word_uint.eq_norm m1mod2k) auto
   325   by (simp only : word_pred_0_n1 word_uint.eq_norm m1mod2k) auto
   327 lemmas word_n1_ge [simp]  = word_m1_ge [simplified word_sp_01]
   327 lemmas word_n1_ge [simp]  = word_m1_ge [simplified word_sp_01]
   328 
   328 
   329 lemmas word_not_simps [simp] = 
   329 lemmas word_not_simps [simp] = 
   330   word_zero_le [THEN leD] word_m1_ge [THEN leD] word_n1_ge [THEN leD]
   330   word_zero_le [THEN leD] word_m1_ge [THEN leD] word_n1_ge [THEN leD]
   331 
   331 
   332 lemma word_gt_0: "0 < y = (0 ~= (y :: 'a :: len0 word))"
   332 lemma word_gt_0: "0 < y = (0 ~= (y :: 'a word))"
   333   unfolding word_less_def by auto
   333   unfolding word_less_def by auto
   334 
   334 
   335 lemmas word_gt_0_no [simp] = word_gt_0 [of "number_of ?y"]
   335 lemmas word_gt_0_no [simp] = word_gt_0 [of "number_of ?y"]
   336 
   336 
   337 lemma word_sless_alt: "(a <s b) == (sint a < sint b)"
   337 lemma word_sless_alt: "(a <s b) == (sint a < sint b)"
   345 lemma word_less_nat_alt: "(a < b) = (unat a < unat b)"
   345 lemma word_less_nat_alt: "(a < b) = (unat a < unat b)"
   346   unfolding unat_def word_less_alt
   346   unfolding unat_def word_less_alt
   347   by (rule nat_less_eq_zless [symmetric]) simp
   347   by (rule nat_less_eq_zless [symmetric]) simp
   348   
   348   
   349 lemma wi_less: 
   349 lemma wi_less: 
   350   "(word_of_int n < (word_of_int m :: 'a :: len0 word)) = 
   350   "(word_of_int n < (word_of_int m :: 'a word)) = 
   351     (n mod 2 ^ len_of TYPE('a) < m mod 2 ^ len_of TYPE('a))"
   351     (n mod 2 ^ CARD('a) < m mod 2 ^ CARD('a))"
   352   unfolding word_less_alt by (simp add: word_uint.eq_norm)
   352   unfolding word_less_alt by (simp add: word_uint.eq_norm)
   353 
   353 
   354 lemma wi_le: 
   354 lemma wi_le: 
   355   "(word_of_int n <= (word_of_int m :: 'a :: len0 word)) = 
   355   "(word_of_int n <= (word_of_int m :: 'a word)) = 
   356     (n mod 2 ^ len_of TYPE('a) <= m mod 2 ^ len_of TYPE('a))"
   356     (n mod 2 ^ CARD('a) <= m mod 2 ^ CARD('a))"
   357   unfolding word_le_def by (simp add: word_uint.eq_norm)
   357   unfolding word_le_def by (simp add: word_uint.eq_norm)
   358 
   358 
   359 lemmas unat_mono = word_less_nat_alt [THEN iffD1, standard]
   359 lemmas unat_mono = word_less_nat_alt [THEN iffD1, standard]
   360 
   360 
   361 
   361 
   362 subsection "Divisibility"
   362 subsection "Divisibility"
   363 
   363 
   364 definition
   364 definition
   365   udvd :: "'a::len word \<Rightarrow> 'a word \<Rightarrow> bool" (infixl "udvd" 50) where
   365   udvd :: "'a::finite word \<Rightarrow> 'a word \<Rightarrow> bool" (infixl "udvd" 50) where
   366   "a udvd b \<equiv> \<exists>n\<ge>0. uint b = n * uint a"
   366   "a udvd b \<equiv> \<exists>n\<ge>0. uint b = n * uint a"
   367 
   367 
   368 lemma udvdI: 
   368 lemma udvdI: 
   369   "0 \<le> n ==> uint b = n * uint a ==> a udvd b"
   369   "0 \<le> n ==> uint b = n * uint a ==> a udvd b"
   370   by (auto simp: udvd_def)
   370   by (auto simp: udvd_def)
   386   unfolding dvd_def udvd_nat_alt by force
   386   unfolding dvd_def udvd_nat_alt by force
   387 
   387 
   388 
   388 
   389 subsection "Division with remainder"
   389 subsection "Division with remainder"
   390 
   390 
   391 instance word :: (len0) Divides.div
   391 instance word :: (type) Divides.div
   392   word_div_def: "a div b == word_of_int (uint a div uint b)"
   392   word_div_def: "a div b == word_of_int (uint a div uint b)"
   393   word_mod_def: "a mod b == word_of_int (uint a mod uint b)"
   393   word_mod_def: "a mod b == word_of_int (uint a mod uint b)"
   394   ..
   394   ..
   395 
   395 
   396 lemmas word_div_no [simp] = 
   396 lemmas word_div_no [simp] = 
   403   [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard]
   403   [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard]
   404 lemmas uint_mod_alt = word_mod_def
   404 lemmas uint_mod_alt = word_mod_def
   405   [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard]
   405   [THEN meta_eq_to_obj_eq [THEN trans [OF uint_cong int_word_uint]], standard]
   406 
   406 
   407 
   407 
   408 lemma word_zero_neq_one: "0 < len_of TYPE ('a :: len0) ==> (0 :: 'a word) ~= 1";
   408 lemma word_zero_neq_one: "0 < CARD('a) ==> (0 :: 'a word) ~= 1";
   409   unfolding word_arith_wis
   409   unfolding word_arith_wis
   410   by (auto simp add: word_ubin.norm_eq_iff [symmetric] gr0_conv_Suc)
   410   by (auto simp add: word_ubin.norm_eq_iff [symmetric] gr0_conv_Suc)
   411 
   411 
   412 lemmas lenw1_zero_neq_one = len_gt_0 [THEN word_zero_neq_one]
   412 lemmas lenw1_zero_neq_one = zero_less_card_finite [THEN word_zero_neq_one]
   413 
   413 
   414 lemma no_no [simp] : "number_of (number_of b) = number_of b"
   414 lemma no_no [simp] : "number_of (number_of b) = number_of b"
   415   by (simp add: number_of_eq)
   415   by (simp add: number_of_eq)
   416 
   416 
   417 lemma unat_minus_one: "x ~= 0 ==> unat (x - 1) = unat x - 1"
   417 lemma unat_minus_one: "x ~= 0 ==> unat (x - 1) = unat x - 1"
   443   add_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard]
   443   add_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard]
   444 lemmas uint_mult_ge0 [simp] =
   444 lemmas uint_mult_ge0 [simp] =
   445   mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard]
   445   mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0, standard]
   446 
   446 
   447 lemma uint_sub_lt2p [simp]: 
   447 lemma uint_sub_lt2p [simp]: 
   448   "uint (x :: 'a :: len0 word) - uint (y :: 'b :: len0 word) < 
   448   "uint (x :: 'a word) - uint (y :: 'b word) < 
   449     2 ^ len_of TYPE('a)"
   449     2 ^ CARD('a)"
   450   using uint_ge_0 [of y] uint_lt2p [of x] by arith
   450   using uint_ge_0 [of y] uint_lt2p [of x] by arith
   451 
   451 
   452 
   452 
   453 subsection "Conditions for the addition (etc) of two words to overflow"
   453 subsection "Conditions for the addition (etc) of two words to overflow"
   454 
   454 
   455 lemma uint_add_lem: 
   455 lemma uint_add_lem: 
   456   "(uint x + uint y < 2 ^ len_of TYPE('a)) = 
   456   "(uint x + uint y < 2 ^ CARD('a)) = 
   457     (uint (x + y :: 'a :: len0 word) = uint x + uint y)"
   457     (uint (x + y :: 'a word) = uint x + uint y)"
   458   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
   458   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
   459 
   459 
   460 lemma uint_mult_lem: 
   460 lemma uint_mult_lem: 
   461   "(uint x * uint y < 2 ^ len_of TYPE('a)) = 
   461   "(uint x * uint y < 2 ^ CARD('a)) = 
   462     (uint (x * y :: 'a :: len0 word) = uint x * uint y)"
   462     (uint (x * y :: 'a word) = uint x * uint y)"
   463   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
   463   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
   464 
   464 
   465 lemma uint_sub_lem: 
   465 lemma uint_sub_lem: 
   466   "(uint x >= uint y) = (uint (x - y) = uint x - uint y)"
   466   "(uint x >= uint y) = (uint (x - y) = uint x - uint y)"
   467   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
   467   by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
   479 
   479 
   480 
   480 
   481 subsection {* Definition of uint\_arith *}
   481 subsection {* Definition of uint\_arith *}
   482 
   482 
   483 lemma word_of_int_inverse:
   483 lemma word_of_int_inverse:
   484   "word_of_int r = a ==> 0 <= r ==> r < 2 ^ len_of TYPE('a) ==> 
   484   "word_of_int r = a ==> 0 <= r ==> r < 2 ^ CARD('a) ==> 
   485    uint (a::'a::len0 word) = r"
   485    uint (a::'a word) = r"
   486   apply (erule word_uint.Abs_inverse' [rotated])
   486   apply (erule word_uint.Abs_inverse' [rotated])
   487   apply (simp add: uints_num)
   487   apply (simp add: uints_num)
   488   done
   488   done
   489 
   489 
   490 lemma uint_split:
   490 lemma uint_split:
   491   fixes x::"'a::len0 word"
   491   fixes x::"'a word"
   492   shows "P (uint x) = 
   492   shows "P (uint x) = 
   493          (ALL i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) --> P i)"
   493          (ALL i. word_of_int i = x & 0 <= i & i < 2^CARD('a) --> P i)"
   494   apply (fold word_int_case_def)
   494   apply (fold word_int_case_def)
   495   apply (auto dest!: word_of_int_inverse simp: int_word_uint int_mod_eq'
   495   apply (auto dest!: word_of_int_inverse simp: int_word_uint int_mod_eq'
   496               split: word_int_split)
   496               split: word_int_split)
   497   done
   497   done
   498 
   498 
   499 lemma uint_split_asm:
   499 lemma uint_split_asm:
   500   fixes x::"'a::len0 word"
   500   fixes x::"'a word"
   501   shows "P (uint x) = 
   501   shows "P (uint x) = 
   502          (~(EX i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) & ~ P i))"
   502          (~(EX i. word_of_int i = x & 0 <= i & i < 2^CARD('a) & ~ P i))"
   503   by (auto dest!: word_of_int_inverse 
   503   by (auto dest!: word_of_int_inverse 
   504            simp: int_word_uint int_mod_eq'
   504            simp: int_word_uint int_mod_eq'
   505            split: uint_split)
   505            split: uint_split)
   506 
   506 
   507 lemmas uint_splits = uint_split uint_split_asm
   507 lemmas uint_splits = uint_split uint_split_asm
   509 lemmas uint_arith_simps = 
   509 lemmas uint_arith_simps = 
   510   word_le_def word_less_alt
   510   word_le_def word_less_alt
   511   word_uint.Rep_inject [symmetric] 
   511   word_uint.Rep_inject [symmetric] 
   512   uint_sub_if' uint_plus_if'
   512   uint_sub_if' uint_plus_if'
   513 
   513 
   514 (* use this to stop, eg, 2 ^ len_of TYPE (32) being simplified *)
   514 (* use this to stop, eg, 2 ^ CARD(32) being simplified *)
   515 lemma power_False_cong: "False ==> a ^ b = c ^ d" 
   515 lemma power_False_cong: "False ==> a ^ b = c ^ d" 
   516   by auto
   516   by auto
   517 
   517 
   518 (* uint_arith_tac: reduce to arithmetic on int, try to solve by arith *)
   518 (* uint_arith_tac: reduce to arithmetic on int, try to solve by arith *)
   519 ML {*
   519 ML {*
   548 
   548 
   549 
   549 
   550 subsection "More on overflows and monotonicity"
   550 subsection "More on overflows and monotonicity"
   551 
   551 
   552 lemma no_plus_overflow_uint_size: 
   552 lemma no_plus_overflow_uint_size: 
   553   "((x :: 'a :: len0 word) <= x + y) = (uint x + uint y < 2 ^ size x)"
   553   "((x :: 'a word) <= x + y) = (uint x + uint y < 2 ^ size x)"
   554   unfolding word_size by uint_arith
   554   unfolding word_size by uint_arith
   555 
   555 
   556 lemmas no_olen_add = no_plus_overflow_uint_size [unfolded word_size]
   556 lemmas no_olen_add = no_plus_overflow_uint_size [unfolded word_size]
   557 
   557 
   558 lemma no_ulen_sub: "((x :: 'a :: len0 word) >= x - y) = (uint y <= uint x)"
   558 lemma no_ulen_sub: "((x :: 'a word) >= x - y) = (uint y <= uint x)"
   559   by uint_arith
   559   by uint_arith
   560 
   560 
   561 lemma no_olen_add':
   561 lemma no_olen_add':
   562   fixes x :: "'a::len0 word"
   562   fixes x :: "'a word"
   563   shows "(x \<le> y + x) = (uint y + uint x < 2 ^ len_of TYPE('a))"
   563   shows "(x \<le> y + x) = (uint y + uint x < 2 ^ CARD('a))"
   564   by (simp add: word_add_ac add_ac no_olen_add)
   564   by (simp add: word_add_ac add_ac no_olen_add)
   565 
   565 
   566 lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric], standard]
   566 lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric], standard]
   567 
   567 
   568 lemmas uint_plus_simple_iff = trans [OF no_olen_add uint_add_lem, standard]
   568 lemmas uint_plus_simple_iff = trans [OF no_olen_add uint_add_lem, standard]
   571 lemmas uint_minus_simple_alt = uint_sub_lem [folded word_le_def]
   571 lemmas uint_minus_simple_alt = uint_sub_lem [folded word_le_def]
   572 lemmas word_sub_le_iff = no_ulen_sub [folded word_le_def]
   572 lemmas word_sub_le_iff = no_ulen_sub [folded word_le_def]
   573 lemmas word_sub_le = word_sub_le_iff [THEN iffD2, standard]
   573 lemmas word_sub_le = word_sub_le_iff [THEN iffD2, standard]
   574 
   574 
   575 lemma word_less_sub1: 
   575 lemma word_less_sub1: 
   576   "(x :: 'a :: len word) ~= 0 ==> (1 < x) = (0 < x - 1)"
   576   "(x :: 'a :: finite word) ~= 0 ==> (1 < x) = (0 < x - 1)"
   577   by uint_arith
   577   by uint_arith
   578 
   578 
   579 lemma word_le_sub1: 
   579 lemma word_le_sub1: 
   580   "(x :: 'a :: len word) ~= 0 ==> (1 <= x) = (0 <= x - 1)"
   580   "(x :: 'a :: finite word) ~= 0 ==> (1 <= x) = (0 <= x - 1)"
   581   by uint_arith
   581   by uint_arith
   582 
   582 
   583 lemma sub_wrap_lt: 
   583 lemma sub_wrap_lt: 
   584   "((x :: 'a :: len0 word) < x - z) = (x < z)"
   584   "((x :: 'a word) < x - z) = (x < z)"
   585   by uint_arith
   585   by uint_arith
   586 
   586 
   587 lemma sub_wrap: 
   587 lemma sub_wrap: 
   588   "((x :: 'a :: len0 word) <= x - z) = (z = 0 | x < z)"
   588   "((x :: 'a word) <= x - z) = (z = 0 | x < z)"
   589   by uint_arith
   589   by uint_arith
   590 
   590 
   591 lemma plus_minus_not_NULL_ab: 
   591 lemma plus_minus_not_NULL_ab: 
   592   "(x :: 'a :: len0 word) <= ab - c ==> c <= ab ==> c ~= 0 ==> x + c ~= 0"
   592   "(x :: 'a word) <= ab - c ==> c <= ab ==> c ~= 0 ==> x + c ~= 0"
   593   by uint_arith
   593   by uint_arith
   594 
   594 
   595 lemma plus_minus_no_overflow_ab: 
   595 lemma plus_minus_no_overflow_ab: 
   596   "(x :: 'a :: len0 word) <= ab - c ==> c <= ab ==> x <= x + c" 
   596   "(x :: 'a word) <= ab - c ==> c <= ab ==> x <= x + c" 
   597   by uint_arith
   597   by uint_arith
   598 
   598 
   599 lemma le_minus': 
   599 lemma le_minus': 
   600   "(a :: 'a :: len0 word) + c <= b ==> a <= a + c ==> c <= b - a"
   600   "(a :: 'a word) + c <= b ==> a <= a + c ==> c <= b - a"
   601   by uint_arith
   601   by uint_arith
   602 
   602 
   603 lemma le_plus': 
   603 lemma le_plus': 
   604   "(a :: 'a :: len0 word) <= b ==> c <= b - a ==> a + c <= b"
   604   "(a :: 'a word) <= b ==> c <= b - a ==> a + c <= b"
   605   by uint_arith
   605   by uint_arith
   606 
   606 
   607 lemmas le_plus = le_plus' [rotated]
   607 lemmas le_plus = le_plus' [rotated]
   608 
   608 
   609 lemmas le_minus = leD [THEN thin_rl, THEN le_minus', standard]
   609 lemmas le_minus = leD [THEN thin_rl, THEN le_minus', standard]
   610 
   610 
   611 lemma word_plus_mono_right: 
   611 lemma word_plus_mono_right: 
   612   "(y :: 'a :: len0 word) <= z ==> x <= x + z ==> x + y <= x + z"
   612   "(y :: 'a word) <= z ==> x <= x + z ==> x + y <= x + z"
   613   by uint_arith
   613   by uint_arith
   614 
   614 
   615 lemma word_less_minus_cancel: 
   615 lemma word_less_minus_cancel: 
   616   "y - x < z - x ==> x <= z ==> (y :: 'a :: len0 word) < z"
   616   "y - x < z - x ==> x <= z ==> (y :: 'a word) < z"
   617   by uint_arith
   617   by uint_arith
   618 
   618 
   619 lemma word_less_minus_mono_left: 
   619 lemma word_less_minus_mono_left: 
   620   "(y :: 'a :: len0 word) < z ==> x <= y ==> y - x < z - x"
   620   "(y :: 'a word) < z ==> x <= y ==> y - x < z - x"
   621   by uint_arith
   621   by uint_arith
   622 
   622 
   623 lemma word_less_minus_mono:  
   623 lemma word_less_minus_mono:  
   624   "a < c ==> d < b ==> a - b < a ==> c - d < c 
   624   "a < c ==> d < b ==> a - b < a ==> c - d < c 
   625   ==> a - b < c - (d::'a::len word)"
   625   ==> a - b < c - (d::'a::finite word)"
   626   by uint_arith
   626   by uint_arith
   627 
   627 
   628 lemma word_le_minus_cancel: 
   628 lemma word_le_minus_cancel: 
   629   "y - x <= z - x ==> x <= z ==> (y :: 'a :: len0 word) <= z"
   629   "y - x <= z - x ==> x <= z ==> (y :: 'a word) <= z"
   630   by uint_arith
   630   by uint_arith
   631 
   631 
   632 lemma word_le_minus_mono_left: 
   632 lemma word_le_minus_mono_left: 
   633   "(y :: 'a :: len0 word) <= z ==> x <= y ==> y - x <= z - x"
   633   "(y :: 'a word) <= z ==> x <= y ==> y - x <= z - x"
   634   by uint_arith
   634   by uint_arith
   635 
   635 
   636 lemma word_le_minus_mono:  
   636 lemma word_le_minus_mono:  
   637   "a <= c ==> d <= b ==> a - b <= a ==> c - d <= c 
   637   "a <= c ==> d <= b ==> a - b <= a ==> c - d <= c 
   638   ==> a - b <= c - (d::'a::len word)"
   638   ==> a - b <= c - (d::'a::finite word)"
   639   by uint_arith
   639   by uint_arith
   640 
   640 
   641 lemma plus_le_left_cancel_wrap: 
   641 lemma plus_le_left_cancel_wrap: 
   642   "(x :: 'a :: len0 word) + y' < x ==> x + y < x ==> (x + y' < x + y) = (y' < y)"
   642   "(x :: 'a word) + y' < x ==> x + y < x ==> (x + y' < x + y) = (y' < y)"
   643   by uint_arith
   643   by uint_arith
   644 
   644 
   645 lemma plus_le_left_cancel_nowrap: 
   645 lemma plus_le_left_cancel_nowrap: 
   646   "(x :: 'a :: len0 word) <= x + y' ==> x <= x + y ==> 
   646   "(x :: 'a word) <= x + y' ==> x <= x + y ==> 
   647     (x + y' < x + y) = (y' < y)" 
   647     (x + y' < x + y) = (y' < y)" 
   648   by uint_arith
   648   by uint_arith
   649 
   649 
   650 lemma word_plus_mono_right2: 
   650 lemma word_plus_mono_right2: 
   651   "(a :: 'a :: len0 word) <= a + b ==> c <= b ==> a <= a + c"
   651   "(a :: 'a word) <= a + b ==> c <= b ==> a <= a + c"
   652   by uint_arith
   652   by uint_arith
   653 
   653 
   654 lemma word_less_add_right: 
   654 lemma word_less_add_right: 
   655   "(x :: 'a :: len0 word) < y - z ==> z <= y ==> x + z < y"
   655   "(x :: 'a word) < y - z ==> z <= y ==> x + z < y"
   656   by uint_arith
   656   by uint_arith
   657 
   657 
   658 lemma word_less_sub_right: 
   658 lemma word_less_sub_right: 
   659   "(x :: 'a :: len0 word) < y + z ==> y <= x ==> x - y < z"
   659   "(x :: 'a word) < y + z ==> y <= x ==> x - y < z"
   660   by uint_arith
   660   by uint_arith
   661 
   661 
   662 lemma word_le_plus_either: 
   662 lemma word_le_plus_either: 
   663   "(x :: 'a :: len0 word) <= y | x <= z ==> y <= y + z ==> x <= y + z"
   663   "(x :: 'a word) <= y | x <= z ==> y <= y + z ==> x <= y + z"
   664   by uint_arith
   664   by uint_arith
   665 
   665 
   666 lemma word_less_nowrapI: 
   666 lemma word_less_nowrapI: 
   667   "(x :: 'a :: len0 word) < z - k ==> k <= z ==> 0 < k ==> x < x + k"
   667   "(x :: 'a word) < z - k ==> k <= z ==> 0 < k ==> x < x + k"
   668   by uint_arith
   668   by uint_arith
   669 
   669 
   670 lemma inc_le: "(i :: 'a :: len word) < m ==> i + 1 <= m"
   670 lemma inc_le: "(i :: 'a :: finite word) < m ==> i + 1 <= m"
   671   by uint_arith
   671   by uint_arith
   672 
   672 
   673 lemma inc_i: 
   673 lemma inc_i: 
   674   "(1 :: 'a :: len word) <= i ==> i < m ==> 1 <= (i + 1) & i + 1 <= m"
   674   "(1 :: 'a :: finite word) <= i ==> i < m ==> 1 <= (i + 1) & i + 1 <= m"
   675   by uint_arith
   675   by uint_arith
   676 
   676 
   677 lemma udvd_incr_lem:
   677 lemma udvd_incr_lem:
   678   "up < uq ==> up = ua + n * uint K ==> 
   678   "up < uq ==> up = ua + n * uint K ==> 
   679     uq = ua + n' * uint K ==> up + uint K <= uq"
   679     uq = ua + n' * uint K ==> up + uint K <= uq"
   727   apply simp
   727   apply simp
   728   done
   728   done
   729 
   729 
   730 subsection "Arithmetic type class instantiations"
   730 subsection "Arithmetic type class instantiations"
   731 
   731 
   732 instance word :: (len0) comm_monoid_add ..
   732 instance word :: (type) comm_monoid_add ..
   733 
   733 
   734 instance word :: (len0) comm_monoid_mult
   734 instance word :: (type) comm_monoid_mult
   735   apply (intro_classes)
   735   apply (intro_classes)
   736    apply (simp add: word_mult_commute)
   736    apply (simp add: word_mult_commute)
   737   apply (simp add: word_mult_1)
   737   apply (simp add: word_mult_1)
   738   done
   738   done
   739 
   739 
   740 instance word :: (len0) comm_semiring 
   740 instance word :: (type) comm_semiring 
   741   by (intro_classes) (simp add : word_left_distrib)
   741   by (intro_classes) (simp add : word_left_distrib)
   742 
   742 
   743 instance word :: (len0) ab_group_add ..
   743 instance word :: (type) ab_group_add ..
   744 
   744 
   745 instance word :: (len0) comm_ring ..
   745 instance word :: (type) comm_ring ..
   746 
   746 
   747 instance word :: (len) comm_semiring_1 
   747 instance word :: (finite) comm_semiring_1 
   748   by (intro_classes) (simp add: lenw1_zero_neq_one)
   748   by (intro_classes) (simp add: lenw1_zero_neq_one)
   749 
   749 
   750 instance word :: (len) comm_ring_1 ..
   750 instance word :: (finite) comm_ring_1 ..
   751 
   751 
   752 instance word :: (len0) comm_semiring_0 ..
   752 instance word :: (type) comm_semiring_0 ..
   753 
   753 
   754 instance word :: (len) recpower
   754 instance word :: (finite) recpower
   755   by (intro_classes) (simp_all add: word_pow)
   755   by (intro_classes) (simp_all add: word_pow)
   756 
   756 
   757 (* note that iszero_def is only for class comm_semiring_1_cancel,
   757 (* note that iszero_def is only for class comm_semiring_1_cancel,
   758    which requires word length >= 1, ie 'a :: len word *) 
   758    which requires word length >= 1, ie 'a :: finite word *) 
   759 lemma zero_bintrunc:
   759 lemma zero_bintrunc:
   760   "iszero (number_of x :: 'a :: len word) = 
   760   "iszero (number_of x :: 'a :: finite word) = 
   761     (bintrunc (len_of TYPE('a)) x = Numeral.Pls)"
   761     (bintrunc CARD('a) x = Numeral.Pls)"
   762   apply (unfold iszero_def word_0_wi word_no_wi)
   762   apply (unfold iszero_def word_0_wi word_no_wi)
   763   apply (rule word_ubin.norm_eq_iff [symmetric, THEN trans])
   763   apply (rule word_ubin.norm_eq_iff [symmetric, THEN trans])
   764   apply (simp add : Pls_def [symmetric])
   764   apply (simp add : Pls_def [symmetric])
   765   done
   765   done
   766 
   766 
   779 lemma word_of_int_nat: 
   779 lemma word_of_int_nat: 
   780   "0 <= x ==> word_of_int x = of_nat (nat x)"
   780   "0 <= x ==> word_of_int x = of_nat (nat x)"
   781   by (simp add: of_nat_nat word_of_int)
   781   by (simp add: of_nat_nat word_of_int)
   782 
   782 
   783 lemma word_number_of_eq: 
   783 lemma word_number_of_eq: 
   784   "number_of w = (of_int w :: 'a :: len word)"
   784   "number_of w = (of_int w :: 'a :: finite word)"
   785   unfolding word_number_of_def word_of_int by auto
   785   unfolding word_number_of_def word_of_int by auto
   786 
   786 
   787 instance word :: (len) number_ring
   787 instance word :: (finite) number_ring
   788   by (intro_classes) (simp add : word_number_of_eq)
   788   by (intro_classes) (simp add : word_number_of_eq)
   789 
   789 
   790 lemma iszero_word_no [simp] : 
   790 lemma iszero_word_no [simp] : 
   791   "iszero (number_of bin :: 'a :: len word) = 
   791   "iszero (number_of bin :: 'a :: finite word) = 
   792     iszero (number_of (bintrunc (len_of TYPE('a)) bin) :: int)"
   792     iszero (number_of (bintrunc CARD('a) bin) :: int)"
   793   apply (simp add: zero_bintrunc number_of_is_id)
   793   apply (simp add: zero_bintrunc number_of_is_id)
   794   apply (unfold iszero_def Pls_def)
   794   apply (unfold iszero_def Pls_def)
   795   apply (rule refl)
   795   apply (rule refl)
   796   done
   796   done
   797     
   797     
   798 
   798 
   799 subsection "Word and nat"
   799 subsection "Word and nat"
   800 
   800 
   801 lemma td_ext_unat':
   801 lemma td_ext_unat':
   802   "n = len_of TYPE ('a :: len) ==> 
   802   "n = CARD('a :: finite) ==> 
   803     td_ext (unat :: 'a word => nat) of_nat 
   803     td_ext (unat :: 'a word => nat) of_nat 
   804     (unats n) (%i. i mod 2 ^ n)"
   804     (unats n) (%i. i mod 2 ^ n)"
   805   apply (unfold td_ext_def' unat_def word_of_nat unats_uints)
   805   apply (unfold td_ext_def' unat_def word_of_nat unats_uints)
   806   apply (auto intro!: imageI simp add : word_of_int_hom_syms)
   806   apply (auto intro!: imageI simp add : word_of_int_hom_syms)
   807   apply (erule word_uint.Abs_inverse [THEN arg_cong])
   807   apply (erule word_uint.Abs_inverse [THEN arg_cong])
   810 
   810 
   811 lemmas td_ext_unat = refl [THEN td_ext_unat']
   811 lemmas td_ext_unat = refl [THEN td_ext_unat']
   812 lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm, standard]
   812 lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm, standard]
   813 
   813 
   814 interpretation word_unat:
   814 interpretation word_unat:
   815   td_ext ["unat::'a::len word => nat" 
   815   td_ext ["unat::'a::finite word => nat" 
   816           of_nat 
   816           of_nat 
   817           "unats (len_of TYPE('a::len))"
   817           "unats CARD('a::finite)"
   818           "%i. i mod 2 ^ len_of TYPE('a::len)"]
   818           "%i. i mod 2 ^ CARD('a::finite)"]
   819   by (rule td_ext_unat)
   819   by (rule td_ext_unat)
   820 
   820 
   821 lemmas td_unat = word_unat.td_thm
   821 lemmas td_unat = word_unat.td_thm
   822 
   822 
   823 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq]
   823 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq]
   824 
   824 
   825 lemma unat_le: "y <= unat (z :: 'a :: len word) ==> y : unats (len_of TYPE ('a))"
   825 lemma unat_le: "y <= unat (z :: 'a :: finite word) ==> y : unats CARD('a)"
   826   apply (unfold unats_def)
   826   apply (unfold unats_def)
   827   apply clarsimp
   827   apply clarsimp
   828   apply (rule xtrans, rule unat_lt2p, assumption) 
   828   apply (rule xtrans, rule unat_lt2p, assumption) 
   829   done
   829   done
   830 
   830 
   831 lemma word_nchotomy:
   831 lemma word_nchotomy:
   832   "ALL w. EX n. (w :: 'a :: len word) = of_nat n & n < 2 ^ len_of TYPE ('a)"
   832   "ALL w. EX n. (w :: 'a :: finite word) = of_nat n & n < 2 ^ CARD('a)"
   833   apply (rule allI)
   833   apply (rule allI)
   834   apply (rule word_unat.Abs_cases)
   834   apply (rule word_unat.Abs_cases)
   835   apply (unfold unats_def)
   835   apply (unfold unats_def)
   836   apply auto
   836   apply auto
   837   done
   837   done
   838 
   838 
   839 lemma of_nat_eq:
   839 lemma of_nat_eq:
   840   fixes w :: "'a::len word"
   840   fixes w :: "'a::finite word"
   841   shows "(of_nat n = w) = (\<exists>q. n = unat w + q * 2 ^ len_of TYPE('a))"
   841   shows "(of_nat n = w) = (\<exists>q. n = unat w + q * 2 ^ CARD('a))"
   842   apply (rule trans)
   842   apply (rule trans)
   843    apply (rule word_unat.inverse_norm)
   843    apply (rule word_unat.inverse_norm)
   844   apply (rule iffI)
   844   apply (rule iffI)
   845    apply (rule mod_eqD)
   845    apply (rule mod_eqD)
   846    apply simp
   846    apply simp
   850 lemma of_nat_eq_size: 
   850 lemma of_nat_eq_size: 
   851   "(of_nat n = w) = (EX q. n = unat w + q * 2 ^ size w)"
   851   "(of_nat n = w) = (EX q. n = unat w + q * 2 ^ size w)"
   852   unfolding word_size by (rule of_nat_eq)
   852   unfolding word_size by (rule of_nat_eq)
   853 
   853 
   854 lemma of_nat_0:
   854 lemma of_nat_0:
   855   "(of_nat m = (0::'a::len word)) = (\<exists>q. m = q * 2 ^ len_of TYPE('a))"
   855   "(of_nat m = (0::'a::finite word)) = (\<exists>q. m = q * 2 ^ CARD('a))"
   856   by (simp add: of_nat_eq)
   856   by (simp add: of_nat_eq)
   857 
   857 
   858 lemmas of_nat_2p = mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]]
   858 lemmas of_nat_2p = mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]]
   859 
   859 
   860 lemma of_nat_gt_0: "of_nat k ~= 0 ==> 0 < k"
   860 lemma of_nat_gt_0: "of_nat k ~= 0 ==> 0 < k"
   861   by (cases k) auto
   861   by (cases k) auto
   862 
   862 
   863 lemma of_nat_neq_0: 
   863 lemma of_nat_neq_0: 
   864   "0 < k ==> k < 2 ^ len_of TYPE ('a :: len) ==> of_nat k ~= (0 :: 'a word)"
   864   "0 < k ==> k < 2 ^ CARD('a :: finite) ==> of_nat k ~= (0 :: 'a word)"
   865   by (clarsimp simp add : of_nat_0)
   865   by (clarsimp simp add : of_nat_0)
   866 
   866 
   867 lemma Abs_fnat_hom_add:
   867 lemma Abs_fnat_hom_add:
   868   "of_nat a + of_nat b = of_nat (a + b)"
   868   "of_nat a + of_nat b = of_nat (a + b)"
   869   by simp
   869   by simp
   870 
   870 
   871 lemma Abs_fnat_hom_mult:
   871 lemma Abs_fnat_hom_mult:
   872   "of_nat a * of_nat b = (of_nat (a * b) :: 'a :: len word)"
   872   "of_nat a * of_nat b = (of_nat (a * b) :: 'a :: finite word)"
   873   by (simp add: word_of_nat word_of_int_mult_hom zmult_int)
   873   by (simp add: word_of_nat word_of_int_mult_hom zmult_int)
   874 
   874 
   875 lemma Abs_fnat_hom_Suc:
   875 lemma Abs_fnat_hom_Suc:
   876   "word_succ (of_nat a) = of_nat (Suc a)"
   876   "word_succ (of_nat a) = of_nat (Suc a)"
   877   by (simp add: word_of_nat word_of_int_succ_hom add_ac)
   877   by (simp add: word_of_nat word_of_int_succ_hom add_ac)
   878 
   878 
   879 lemma Abs_fnat_hom_0: "(0::'a::len word) = of_nat 0"
   879 lemma Abs_fnat_hom_0: "(0::'a::finite word) = of_nat 0"
   880   by (simp add: word_of_nat word_0_wi)
   880   by (simp add: word_of_nat word_0_wi)
   881 
   881 
   882 lemma Abs_fnat_hom_1: "(1::'a::len word) = of_nat (Suc 0)"
   882 lemma Abs_fnat_hom_1: "(1::'a::finite word) = of_nat (Suc 0)"
   883   by (simp add: word_of_nat word_1_wi)
   883   by (simp add: word_of_nat word_1_wi)
   884 
   884 
   885 lemmas Abs_fnat_homs = 
   885 lemmas Abs_fnat_homs = 
   886   Abs_fnat_hom_add Abs_fnat_hom_mult Abs_fnat_hom_Suc 
   886   Abs_fnat_hom_add Abs_fnat_hom_mult Abs_fnat_hom_Suc 
   887   Abs_fnat_hom_0 Abs_fnat_hom_1
   887   Abs_fnat_hom_0 Abs_fnat_hom_1
   919 
   919 
   920 lemmas word_sub_less_iff = word_sub_le_iff
   920 lemmas word_sub_less_iff = word_sub_le_iff
   921   [simplified linorder_not_less [symmetric], simplified]
   921   [simplified linorder_not_less [symmetric], simplified]
   922 
   922 
   923 lemma unat_add_lem: 
   923 lemma unat_add_lem: 
   924   "(unat x + unat y < 2 ^ len_of TYPE('a)) = 
   924   "(unat x + unat y < 2 ^ CARD('a)) = 
   925     (unat (x + y :: 'a :: len word) = unat x + unat y)"
   925     (unat (x + y :: 'a :: finite word) = unat x + unat y)"
   926   unfolding unat_word_ariths
   926   unfolding unat_word_ariths
   927   by (auto intro!: trans [OF _ nat_mod_lem])
   927   by (auto intro!: trans [OF _ nat_mod_lem])
   928 
   928 
   929 lemma unat_mult_lem: 
   929 lemma unat_mult_lem: 
   930   "(unat x * unat y < 2 ^ len_of TYPE('a)) = 
   930   "(unat x * unat y < 2 ^ CARD('a)) = 
   931     (unat (x * y :: 'a :: len word) = unat x * unat y)"
   931     (unat (x * y :: 'a :: finite word) = unat x * unat y)"
   932   unfolding unat_word_ariths
   932   unfolding unat_word_ariths
   933   by (auto intro!: trans [OF _ nat_mod_lem])
   933   by (auto intro!: trans [OF _ nat_mod_lem])
   934 
   934 
   935 lemmas unat_plus_if' = 
   935 lemmas unat_plus_if' = 
   936   trans [OF unat_word_ariths(1) mod_nat_add, simplified, standard]
   936   trans [OF unat_word_ariths(1) mod_nat_add, simplified, standard]
   937 
   937 
   938 lemma le_no_overflow: 
   938 lemma le_no_overflow: 
   939   "x <= b ==> a <= a + b ==> x <= a + (b :: 'a :: len0 word)"
   939   "x <= b ==> a <= a + b ==> x <= a + (b :: 'a word)"
   940   apply (erule order_trans)
   940   apply (erule order_trans)
   941   apply (erule olen_add_eqv [THEN iffD1])
   941   apply (erule olen_add_eqv [THEN iffD1])
   942   done
   942   done
   943 
   943 
   944 lemmas un_ui_le = trans 
   944 lemmas un_ui_le = trans 
   965   apply uint_arith
   965   apply uint_arith
   966   done
   966   done
   967 
   967 
   968 lemmas unat_sub_if' = unat_sub_if_size [unfolded word_size]
   968 lemmas unat_sub_if' = unat_sub_if_size [unfolded word_size]
   969 
   969 
   970 lemma unat_div: "unat ((x :: 'a :: len word) div y) = unat x div unat y"
   970 lemma unat_div: "unat ((x :: 'a :: finite word) div y) = unat x div unat y"
   971   apply (simp add : unat_word_ariths)
   971   apply (simp add : unat_word_ariths)
   972   apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
   972   apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
   973   apply (rule div_le_dividend)
   973   apply (rule div_le_dividend)
   974   done
   974   done
   975 
   975 
   976 lemma unat_mod: "unat ((x :: 'a :: len word) mod y) = unat x mod unat y"
   976 lemma unat_mod: "unat ((x :: 'a :: finite word) mod y) = unat x mod unat y"
   977   apply (clarsimp simp add : unat_word_ariths)
   977   apply (clarsimp simp add : unat_word_ariths)
   978   apply (cases "unat y")
   978   apply (cases "unat y")
   979    prefer 2
   979    prefer 2
   980    apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
   980    apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
   981    apply (rule mod_le_divisor)
   981    apply (rule mod_le_divisor)
   982    apply auto
   982    apply auto
   983   done
   983   done
   984 
   984 
   985 lemma uint_div: "uint ((x :: 'a :: len word) div y) = uint x div uint y"
   985 lemma uint_div: "uint ((x :: 'a :: finite word) div y) = uint x div uint y"
   986   unfolding uint_nat by (simp add : unat_div zdiv_int)
   986   unfolding uint_nat by (simp add : unat_div zdiv_int)
   987 
   987 
   988 lemma uint_mod: "uint ((x :: 'a :: len word) mod y) = uint x mod uint y"
   988 lemma uint_mod: "uint ((x :: 'a :: finite word) mod y) = uint x mod uint y"
   989   unfolding uint_nat by (simp add : unat_mod zmod_int)
   989   unfolding uint_nat by (simp add : unat_mod zmod_int)
   990 
   990 
   991 
   991 
   992 subsection {* Definition of unat\_arith tactic *}
   992 subsection {* Definition of unat\_arith tactic *}
   993 
   993 
   994 lemma unat_split:
   994 lemma unat_split:
   995   fixes x::"'a::len word"
   995   fixes x::"'a::finite word"
   996   shows "P (unat x) = 
   996   shows "P (unat x) = 
   997          (ALL n. of_nat n = x & n < 2^len_of TYPE('a) --> P n)"
   997          (ALL n. of_nat n = x & n < 2^CARD('a) --> P n)"
   998   by (auto simp: unat_of_nat)
   998   by (auto simp: unat_of_nat)
   999 
   999 
  1000 lemma unat_split_asm:
  1000 lemma unat_split_asm:
  1001   fixes x::"'a::len word"
  1001   fixes x::"'a::finite word"
  1002   shows "P (unat x) = 
  1002   shows "P (unat x) = 
  1003          (~(EX n. of_nat n = x & n < 2^len_of TYPE('a) & ~ P n))"
  1003          (~(EX n. of_nat n = x & n < 2^CARD('a) & ~ P n))"
  1004   by (auto simp: unat_of_nat)
  1004   by (auto simp: unat_of_nat)
  1005 
  1005 
  1006 lemmas of_nat_inverse = 
  1006 lemmas of_nat_inverse = 
  1007   word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified]
  1007   word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified]
  1008 
  1008 
  1042 method_setup unat_arith = 
  1042 method_setup unat_arith = 
  1043   "Method.ctxt_args (fn ctxt => Method.SIMPLE_METHOD (unat_arith_tac ctxt 1))" 
  1043   "Method.ctxt_args (fn ctxt => Method.SIMPLE_METHOD (unat_arith_tac ctxt 1))" 
  1044   "solving word arithmetic via natural numbers and arith"
  1044   "solving word arithmetic via natural numbers and arith"
  1045 
  1045 
  1046 lemma no_plus_overflow_unat_size: 
  1046 lemma no_plus_overflow_unat_size: 
  1047   "((x :: 'a :: len word) <= x + y) = (unat x + unat y < 2 ^ size x)" 
  1047   "((x :: 'a :: finite word) <= x + y) = (unat x + unat y < 2 ^ size x)" 
  1048   unfolding word_size by unat_arith
  1048   unfolding word_size by unat_arith
  1049 
  1049 
  1050 lemma unat_sub: "b <= a ==> unat (a - b) = unat a - unat (b :: 'a :: len word)"
  1050 lemma unat_sub: "b <= a ==> unat (a - b) = unat a - unat (b :: 'a :: finite word)"
  1051   by unat_arith
  1051   by unat_arith
  1052 
  1052 
  1053 lemmas no_olen_add_nat = no_plus_overflow_unat_size [unfolded word_size]
  1053 lemmas no_olen_add_nat = no_plus_overflow_unat_size [unfolded word_size]
  1054 
  1054 
  1055 lemmas unat_plus_simple = trans [OF no_olen_add_nat unat_add_lem, standard]
  1055 lemmas unat_plus_simple = trans [OF no_olen_add_nat unat_add_lem, standard]
  1056 
  1056 
  1057 lemma word_div_mult: 
  1057 lemma word_div_mult: 
  1058   "(0 :: 'a :: len word) < y ==> unat x * unat y < 2 ^ len_of TYPE('a) ==> 
  1058   "(0 :: 'a :: finite word) < y ==> unat x * unat y < 2 ^ CARD('a) ==> 
  1059     x * y div y = x"
  1059     x * y div y = x"
  1060   apply unat_arith
  1060   apply unat_arith
  1061   apply clarsimp
  1061   apply clarsimp
  1062   apply (subst unat_mult_lem [THEN iffD1])
  1062   apply (subst unat_mult_lem [THEN iffD1])
  1063   apply auto
  1063   apply auto
  1064   done
  1064   done
  1065 
  1065 
  1066 lemma div_lt': "(i :: 'a :: len word) <= k div x ==> 
  1066 lemma div_lt': "(i :: 'a :: finite word) <= k div x ==> 
  1067     unat i * unat x < 2 ^ len_of TYPE('a)"
  1067     unat i * unat x < 2 ^ CARD('a)"
  1068   apply unat_arith
  1068   apply unat_arith
  1069   apply clarsimp
  1069   apply clarsimp
  1070   apply (drule mult_le_mono1)
  1070   apply (drule mult_le_mono1)
  1071   apply (erule order_le_less_trans)
  1071   apply (erule order_le_less_trans)
  1072   apply (rule xtr7 [OF unat_lt2p div_mult_le])
  1072   apply (rule xtr7 [OF unat_lt2p div_mult_le])
  1073   done
  1073   done
  1074 
  1074 
  1075 lemmas div_lt'' = order_less_imp_le [THEN div_lt']
  1075 lemmas div_lt'' = order_less_imp_le [THEN div_lt']
  1076 
  1076 
  1077 lemma div_lt_mult: "(i :: 'a :: len word) < k div x ==> 0 < x ==> i * x < k"
  1077 lemma div_lt_mult: "(i :: 'a :: finite word) < k div x ==> 0 < x ==> i * x < k"
  1078   apply (frule div_lt'' [THEN unat_mult_lem [THEN iffD1]])
  1078   apply (frule div_lt'' [THEN unat_mult_lem [THEN iffD1]])
  1079   apply (simp add: unat_arith_simps)
  1079   apply (simp add: unat_arith_simps)
  1080   apply (drule (1) mult_less_mono1)
  1080   apply (drule (1) mult_less_mono1)
  1081   apply (erule order_less_le_trans)
  1081   apply (erule order_less_le_trans)
  1082   apply (rule div_mult_le)
  1082   apply (rule div_mult_le)
  1083   done
  1083   done
  1084 
  1084 
  1085 lemma div_le_mult: 
  1085 lemma div_le_mult: 
  1086   "(i :: 'a :: len word) <= k div x ==> 0 < x ==> i * x <= k"
  1086   "(i :: 'a :: finite word) <= k div x ==> 0 < x ==> i * x <= k"
  1087   apply (frule div_lt' [THEN unat_mult_lem [THEN iffD1]])
  1087   apply (frule div_lt' [THEN unat_mult_lem [THEN iffD1]])
  1088   apply (simp add: unat_arith_simps)
  1088   apply (simp add: unat_arith_simps)
  1089   apply (drule mult_le_mono1)
  1089   apply (drule mult_le_mono1)
  1090   apply (erule order_trans)
  1090   apply (erule order_trans)
  1091   apply (rule div_mult_le)
  1091   apply (rule div_mult_le)
  1092   done
  1092   done
  1093 
  1093 
  1094 lemma div_lt_uint': 
  1094 lemma div_lt_uint': 
  1095   "(i :: 'a :: len word) <= k div x ==> uint i * uint x < 2 ^ len_of TYPE('a)"
  1095   "(i :: 'a :: finite word) <= k div x ==> uint i * uint x < 2 ^ CARD('a)"
  1096   apply (unfold uint_nat)
  1096   apply (unfold uint_nat)
  1097   apply (drule div_lt')
  1097   apply (drule div_lt')
  1098   apply (simp add: zmult_int zless_nat_eq_int_zless [symmetric] 
  1098   apply (simp add: zmult_int zless_nat_eq_int_zless [symmetric] 
  1099                    nat_power_eq)
  1099                    nat_power_eq)
  1100   done
  1100   done
  1101 
  1101 
  1102 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint']
  1102 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint']
  1103 
  1103 
  1104 lemma word_le_exists': 
  1104 lemma word_le_exists': 
  1105   "(x :: 'a :: len0 word) <= y ==> 
  1105   "(x :: 'a word) <= y ==> 
  1106     (EX z. y = x + z & uint x + uint z < 2 ^ len_of TYPE('a))"
  1106     (EX z. y = x + z & uint x + uint z < 2 ^ CARD('a))"
  1107   apply (rule exI)
  1107   apply (rule exI)
  1108   apply (rule conjI)
  1108   apply (rule conjI)
  1109   apply (rule zadd_diff_inverse)
  1109   apply (rule zadd_diff_inverse)
  1110   apply uint_arith
  1110   apply uint_arith
  1111   done
  1111   done
  1137 
  1137 
  1138 lemmas uno_simps [THEN le_unat_uoi, standard] =
  1138 lemmas uno_simps [THEN le_unat_uoi, standard] =
  1139   mod_le_divisor div_le_dividend thd1 
  1139   mod_le_divisor div_le_dividend thd1 
  1140 
  1140 
  1141 lemma word_mod_div_equality:
  1141 lemma word_mod_div_equality:
  1142   "(n div b) * b + (n mod b) = (n :: 'a :: len word)"
  1142   "(n div b) * b + (n mod b) = (n :: 'a :: finite word)"
  1143   apply (unfold word_less_nat_alt word_arith_nat_defs)
  1143   apply (unfold word_less_nat_alt word_arith_nat_defs)
  1144   apply (cut_tac y="unat b" in gt_or_eq_0)
  1144   apply (cut_tac y="unat b" in gt_or_eq_0)
  1145   apply (erule disjE)
  1145   apply (erule disjE)
  1146    apply (simp add: mod_div_equality uno_simps)
  1146    apply (simp add: mod_div_equality uno_simps)
  1147   apply simp
  1147   apply simp
  1148   done
  1148   done
  1149 
  1149 
  1150 lemma word_div_mult_le: "a div b * b <= (a::'a::len word)"
  1150 lemma word_div_mult_le: "a div b * b <= (a::'a::finite word)"
  1151   apply (unfold word_le_nat_alt word_arith_nat_defs)
  1151   apply (unfold word_le_nat_alt word_arith_nat_defs)
  1152   apply (cut_tac y="unat b" in gt_or_eq_0)
  1152   apply (cut_tac y="unat b" in gt_or_eq_0)
  1153   apply (erule disjE)
  1153   apply (erule disjE)
  1154    apply (simp add: div_mult_le uno_simps)
  1154    apply (simp add: div_mult_le uno_simps)
  1155   apply simp
  1155   apply simp
  1156   done
  1156   done
  1157 
  1157 
  1158 lemma word_mod_less_divisor: "0 < n ==> m mod n < (n :: 'a :: len word)"
  1158 lemma word_mod_less_divisor: "0 < n ==> m mod n < (n :: 'a :: finite word)"
  1159   apply (simp only: word_less_nat_alt word_arith_nat_defs)
  1159   apply (simp only: word_less_nat_alt word_arith_nat_defs)
  1160   apply (clarsimp simp add : uno_simps)
  1160   apply (clarsimp simp add : uno_simps)
  1161   done
  1161   done
  1162 
  1162 
  1163 lemma word_of_int_power_hom: 
  1163 lemma word_of_int_power_hom: 
  1164   "word_of_int a ^ n = (word_of_int (a ^ n) :: 'a :: len word)"
  1164   "word_of_int a ^ n = (word_of_int (a ^ n) :: 'a :: finite word)"
  1165   by (induct n) (simp_all add : word_of_int_hom_syms power_Suc)
  1165   by (induct n) (simp_all add : word_of_int_hom_syms power_Suc)
  1166 
  1166 
  1167 lemma word_arith_power_alt: 
  1167 lemma word_arith_power_alt: 
  1168   "a ^ n = (word_of_int (uint a ^ n) :: 'a :: len word)"
  1168   "a ^ n = (word_of_int (uint a ^ n) :: 'a :: finite word)"
  1169   by (simp add : word_of_int_power_hom [symmetric])
  1169   by (simp add : word_of_int_power_hom [symmetric])
  1170 
  1170 
  1171 
  1171 
  1172 subsection "Cardinality, finiteness of set of words"
  1172 subsection "Cardinality, finiteness of set of words"
  1173 
  1173 
  1176 lemmas card_eq = word_unat.Abs_inj_on [THEN card_image,
  1176 lemmas card_eq = word_unat.Abs_inj_on [THEN card_image,
  1177   unfolded word_unat.image, unfolded unats_def, standard]
  1177   unfolded word_unat.image, unfolded unats_def, standard]
  1178 
  1178 
  1179 lemmas card_word = trans [OF card_eq card_lessThan', standard]
  1179 lemmas card_word = trans [OF card_eq card_lessThan', standard]
  1180 
  1180 
  1181 lemma finite_word_UNIV: "finite (UNIV :: 'a :: len word set)"
  1181 lemma finite_word_UNIV: "finite (UNIV :: 'a :: finite word set)"
  1182   apply (rule contrapos_np)
  1182   apply (rule contrapos_np)
  1183    prefer 2
  1183    prefer 2
  1184    apply (erule card_infinite)
  1184    apply (erule card_infinite)
  1185   apply (simp add : card_word)
  1185   apply (simp add : card_word)
  1186   done
  1186   done
  1187 
  1187 
  1188 lemma card_word_size: 
  1188 lemma card_word_size: 
  1189   "card (UNIV :: 'a :: len word set) = (2 ^ size (x :: 'a word))"
  1189   "card (UNIV :: 'a :: finite word set) = (2 ^ size (x :: 'a word))"
  1190   unfolding word_size by (rule card_word)
  1190   unfolding word_size by (rule card_word)
  1191 
  1191 
  1192 end 
  1192 end 
  1193 
  1193