src/HOL/Word/Word.thy
changeset 65336 8e5274fc0093
parent 65328 2510b0ce28da
child 65363 5eb619751b14
equal deleted inserted replaced
65335:7634d33c1a79 65336:8e5274fc0093
  3313   apply (unfold slice_take shiftr_bl)
  3313   apply (unfold slice_take shiftr_bl)
  3314   apply (rule ucast_of_bl_up [symmetric])
  3314   apply (rule ucast_of_bl_up [symmetric])
  3315   apply (simp add: word_size)
  3315   apply (simp add: word_size)
  3316   done
  3316   done
  3317 
  3317 
  3318 lemma nth_slice:
  3318 lemma nth_slice: "(slice n w :: 'a::len0 word) !! m = (w !! (m + n) \<and> m < len_of TYPE('a))"
  3319   "(slice n w :: 'a::len0 word) !! m =
  3319   by (simp add: slice_shiftr nth_ucast nth_shiftr)
  3320    (w !! (m + n) & m < len_of TYPE('a))"
       
  3321   unfolding slice_shiftr
       
  3322   by (simp add : nth_ucast nth_shiftr)
       
  3323 
  3320 
  3324 lemma slice1_down_alt':
  3321 lemma slice1_down_alt':
  3325   "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs + k = n \<Longrightarrow>
  3322   "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))"
  3323     to_bl sl = takefill False fs (drop k (to_bl w))"
  3327   unfolding slice1_def word_size of_bl_def uint_bl
  3324   by (auto simp: slice1_def word_size of_bl_def uint_bl
  3328   by (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop drop_takefill)
  3325       word_ubin.eq_norm bl_bin_bl_rep_drop drop_takefill)
  3329 
  3326 
  3330 lemma slice1_up_alt':
  3327 lemma slice1_up_alt':
  3331   "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs = n + k \<Longrightarrow>
  3328   "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))"
  3329     to_bl sl = takefill False fs (replicate k False @ (to_bl w))"
  3333   apply (unfold slice1_def word_size of_bl_def uint_bl)
  3330   apply (unfold slice1_def word_size of_bl_def uint_bl)
  3334   apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop
  3331   apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop takefill_append [symmetric])
  3335                         takefill_append [symmetric])
  3332   apply (rule_tac f = "\<lambda>k. takefill False (len_of TYPE('a))
  3336   apply (rule_tac f = "%k. takefill False (len_of TYPE('a))
       
  3337     (replicate k False @ bin_to_bl (len_of TYPE('b)) (uint w))" in arg_cong)
  3333     (replicate k False @ bin_to_bl (len_of TYPE('b)) (uint w))" in arg_cong)
  3338   apply arith
  3334   apply arith
  3339   done
  3335   done
  3340 
  3336 
  3341 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size]
  3337 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size]
  3344 lemmas slice1_up_alts =
  3340 lemmas slice1_up_alts =
  3345   le_add_diff_inverse [symmetric, THEN su1]
  3341   le_add_diff_inverse [symmetric, THEN su1]
  3346   le_add_diff_inverse2 [symmetric, THEN su1]
  3342   le_add_diff_inverse2 [symmetric, THEN su1]
  3347 
  3343 
  3348 lemma ucast_slice1: "ucast w = slice1 (size w) w"
  3344 lemma ucast_slice1: "ucast w = slice1 (size w) w"
  3349   unfolding slice1_def ucast_bl
  3345   by (simp add: slice1_def ucast_bl takefill_same' word_size)
  3350   by (simp add : takefill_same' word_size)
       
  3351 
  3346 
  3352 lemma ucast_slice: "ucast w = slice 0 w"
  3347 lemma ucast_slice: "ucast w = slice 0 w"
  3353   unfolding slice_def by (simp add : ucast_slice1)
  3348   by (simp add: slice_def ucast_slice1)
  3354 
  3349 
  3355 lemma slice_id: "slice 0 t = t"
  3350 lemma slice_id: "slice 0 t = t"
  3356   by (simp only: ucast_slice [symmetric] ucast_id)
  3351   by (simp only: ucast_slice [symmetric] ucast_id)
  3357 
  3352 
  3358 lemma revcast_slice1 [OF refl]:
  3353 lemma revcast_slice1 [OF refl]: "rc = revcast w \<Longrightarrow> slice1 (size rc) w = rc"
  3359   "rc = revcast w \<Longrightarrow> slice1 (size rc) w = rc"
  3354   by (simp add: slice1_def revcast_def' word_size)
  3360   unfolding slice1_def revcast_def' by (simp add : word_size)
       
  3361 
  3355 
  3362 lemma slice1_tf_tf':
  3356 lemma slice1_tf_tf':
  3363   "to_bl (slice1 n w :: 'a::len0 word) =
  3357   "to_bl (slice1 n w :: 'a::len0 word) =
  3364    rev (takefill False (len_of TYPE('a)) (rev (takefill False n (to_bl w))))"
  3358     rev (takefill False (len_of TYPE('a)) (rev (takefill False n (to_bl w))))"
  3365   unfolding slice1_def by (rule word_rev_tf)
  3359   unfolding slice1_def by (rule word_rev_tf)
  3366 
  3360 
  3367 lemmas slice1_tf_tf = slice1_tf_tf' [THEN word_bl.Rep_inverse', symmetric]
  3361 lemmas slice1_tf_tf = slice1_tf_tf' [THEN word_bl.Rep_inverse', symmetric]
  3368 
  3362 
  3369 lemma rev_slice1:
  3363 lemma rev_slice1:
  3370   "n + k = len_of TYPE('a) + len_of TYPE('b) \<Longrightarrow>
  3364   "n + k = len_of TYPE('a) + len_of TYPE('b) \<Longrightarrow>
  3371   slice1 n (word_reverse w :: 'b::len0 word) =
  3365     slice1 n (word_reverse w :: 'b::len0 word) =
  3372   word_reverse (slice1 k w :: 'a::len0 word)"
  3366     word_reverse (slice1 k w :: 'a::len0 word)"
  3373   apply (unfold word_reverse_def slice1_tf_tf)
  3367   apply (unfold word_reverse_def slice1_tf_tf)
  3374   apply (rule word_bl.Rep_inverse')
  3368   apply (rule word_bl.Rep_inverse')
  3375   apply (rule rev_swap [THEN iffD1])
  3369   apply (rule rev_swap [THEN iffD1])
  3376   apply (rule trans [symmetric])
  3370   apply (rule trans [symmetric])
  3377   apply (rule tf_rev)
  3371    apply (rule tf_rev)
  3378    apply (simp add: word_bl.Abs_inverse)
  3372    apply (simp add: word_bl.Abs_inverse)
  3379   apply (simp add: word_bl.Abs_inverse)
  3373   apply (simp add: word_bl.Abs_inverse)
  3380   done
  3374   done
  3381 
  3375 
  3382 lemma rev_slice:
  3376 lemma rev_slice:
  3383   "n + k + len_of TYPE('a::len0) = len_of TYPE('b::len0) \<Longrightarrow>
  3377   "n + k + len_of TYPE('a::len0) = len_of TYPE('b::len0) \<Longrightarrow>
  3384     slice n (word_reverse (w::'b word)) = word_reverse (slice k w::'a word)"
  3378     slice n (word_reverse (w::'b word)) = word_reverse (slice k w :: 'a word)"
  3385   apply (unfold slice_def word_size)
  3379   apply (unfold slice_def word_size)
  3386   apply (rule rev_slice1)
  3380   apply (rule rev_slice1)
  3387   apply arith
  3381   apply arith
  3388   done
  3382   done
  3389 
  3383 
  3392 
  3386 
  3393 \<comment> \<open>problem posed by TPHOLs referee:
  3387 \<comment> \<open>problem posed by TPHOLs referee:
  3394       criterion for overflow of addition of signed integers\<close>
  3388       criterion for overflow of addition of signed integers\<close>
  3395 
  3389 
  3396 lemma sofl_test:
  3390 lemma sofl_test:
  3397   "(sint (x :: 'a::len word) + sint y = sint (x + y)) =
  3391   "(sint x + sint y = sint (x + y)) =
  3398      ((((x+y) XOR x) AND ((x+y) XOR y)) >> (size x - 1) = 0)"
  3392      ((((x + y) XOR x) AND ((x + y) XOR y)) >> (size x - 1) = 0)"
       
  3393   for x y :: "'a::len word"
  3399   apply (unfold word_size)
  3394   apply (unfold word_size)
  3400   apply (cases "len_of TYPE('a)", simp)
  3395   apply (cases "len_of TYPE('a)", simp)
  3401   apply (subst msb_shift [THEN sym_notr])
  3396   apply (subst msb_shift [THEN sym_notr])
  3402   apply (simp add: word_ops_msb)
  3397   apply (simp add: word_ops_msb)
  3403   apply (simp add: word_msb_sint)
  3398   apply (simp add: word_msb_sint)
  3404   apply safe
  3399   apply safe
  3405        apply simp_all
  3400        apply simp_all
  3406      apply (unfold sint_word_ariths)
  3401      apply (unfold sint_word_ariths)
  3407      apply (unfold word_sbin.set_iff_norm [symmetric] sints_num)
  3402      apply (unfold word_sbin.set_iff_norm [symmetric] sints_num)
  3408      apply safe
  3403      apply safe
  3409         apply (insert sint_range' [where x=x])
  3404          apply (insert sint_range' [where x=x])
  3410         apply (insert sint_range' [where x=y])
  3405          apply (insert sint_range' [where x=y])
  3411         defer
  3406          defer
       
  3407          apply (simp (no_asm), arith)
  3412         apply (simp (no_asm), arith)
  3408         apply (simp (no_asm), arith)
       
  3409        defer
       
  3410        defer
  3413        apply (simp (no_asm), arith)
  3411        apply (simp (no_asm), arith)
  3414       defer
       
  3415       defer
       
  3416       apply (simp (no_asm), arith)
  3412       apply (simp (no_asm), arith)
  3417      apply (simp (no_asm), arith)
  3413      apply (rule notI [THEN notnotD],
  3418     apply (rule notI [THEN notnotD],
  3414       drule leI not_le_imp_less,
  3419            drule leI not_le_imp_less,
  3415       drule sbintrunc_inc sbintrunc_dec,
  3420            drule sbintrunc_inc sbintrunc_dec,
  3416       simp)+
  3421            simp)+
       
  3422   done
  3417   done
  3423 
  3418 
  3424 
  3419 
  3425 subsection \<open>Split and cat\<close>
  3420 subsection \<open>Split and cat\<close>
  3426 
  3421 
  3429 
  3424 
  3430 lemma word_rsplit_no:
  3425 lemma word_rsplit_no:
  3431   "(word_rsplit (numeral bin :: 'b::len0 word) :: 'a word list) =
  3426   "(word_rsplit (numeral bin :: 'b::len0 word) :: 'a word list) =
  3432     map word_of_int (bin_rsplit (len_of TYPE('a::len))
  3427     map word_of_int (bin_rsplit (len_of TYPE('a::len))
  3433       (len_of TYPE('b), bintrunc (len_of TYPE('b)) (numeral bin)))"
  3428       (len_of TYPE('b), bintrunc (len_of TYPE('b)) (numeral bin)))"
  3434   unfolding word_rsplit_def by (simp add: word_ubin.eq_norm)
  3429   by (simp add: word_rsplit_def word_ubin.eq_norm)
  3435 
  3430 
  3436 lemmas word_rsplit_no_cl [simp] = word_rsplit_no
  3431 lemmas word_rsplit_no_cl [simp] = word_rsplit_no
  3437   [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]]
  3432   [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]]
  3438 
  3433 
  3439 lemma test_bit_cat:
  3434 lemma test_bit_cat:
  3440   "wc = word_cat a b \<Longrightarrow> wc !! n = (n < size wc &
  3435   "wc = word_cat a b \<Longrightarrow> wc !! n = (n < size wc \<and>
  3441     (if n < size b then b !! n else a !! (n - size b)))"
  3436     (if n < size b then b !! n else a !! (n - size b)))"
  3442   apply (unfold word_cat_bin' test_bit_bin)
  3437   apply (auto simp: word_cat_bin' test_bit_bin word_ubin.eq_norm nth_bintr bin_nth_cat word_size)
  3443   apply (auto simp add : word_ubin.eq_norm nth_bintr bin_nth_cat word_size)
       
  3444   apply (erule bin_nth_uint_imp)
  3438   apply (erule bin_nth_uint_imp)
  3445   done
  3439   done
  3446 
  3440 
  3447 lemma word_cat_bl: "word_cat a b = of_bl (to_bl a @ to_bl b)"
  3441 lemma word_cat_bl: "word_cat a b = of_bl (to_bl a @ to_bl b)"
  3448   apply (unfold of_bl_def to_bl_def word_cat_bin')
  3442   by (simp add: of_bl_def to_bl_def word_cat_bin' bl_to_bin_app_cat)
  3449   apply (simp add: bl_to_bin_app_cat)
       
  3450   done
       
  3451 
  3443 
  3452 lemma of_bl_append:
  3444 lemma of_bl_append:
  3453   "(of_bl (xs @ ys) :: 'a::len word) = of_bl xs * 2^(length ys) + of_bl ys"
  3445   "(of_bl (xs @ ys) :: 'a::len word) = of_bl xs * 2^(length ys) + of_bl ys"
  3454   apply (unfold of_bl_def)
  3446   apply (simp add: of_bl_def bl_to_bin_app_cat bin_cat_num)
  3455   apply (simp add: bl_to_bin_app_cat bin_cat_num)
       
  3456   apply (simp add: word_of_int_power_hom [symmetric] word_of_int_hom_syms)
  3447   apply (simp add: word_of_int_power_hom [symmetric] word_of_int_hom_syms)
  3457   done
  3448   done
  3458 
  3449 
  3459 lemma of_bl_False [simp]:
  3450 lemma of_bl_False [simp]: "of_bl (False#xs) = of_bl xs"
  3460   "of_bl (False#xs) = of_bl xs"
  3451   by (rule word_eqI) (auto simp: test_bit_of_bl nth_append)
  3461   by (rule word_eqI)
  3452 
  3462      (auto simp add: test_bit_of_bl nth_append)
  3453 lemma of_bl_True [simp]: "(of_bl (True # xs) :: 'a::len word) = 2^length xs + of_bl xs"
  3463 
  3454   by (subst of_bl_append [where xs="[True]", simplified]) (simp add: word_1_bl)
  3464 lemma of_bl_True [simp]:
  3455 
  3465   "(of_bl (True#xs)::'a::len word) = 2^length xs + of_bl xs"
  3456 lemma of_bl_Cons: "of_bl (x#xs) = of_bool x * 2^length xs + of_bl xs"
  3466   by (subst of_bl_append [where xs="[True]", simplified])
       
  3467      (simp add: word_1_bl)
       
  3468 
       
  3469 lemma of_bl_Cons:
       
  3470   "of_bl (x#xs) = of_bool x * 2^length xs + of_bl xs"
       
  3471   by (cases x) simp_all
  3457   by (cases x) simp_all
  3472 
  3458 
  3473 lemma split_uint_lem: "bin_split n (uint (w :: 'a::len0 word)) = (a, b) \<Longrightarrow>
  3459 lemma split_uint_lem: "bin_split n (uint w) = (a, b) \<Longrightarrow>
  3474   a = bintrunc (len_of TYPE('a) - n) a & b = bintrunc (len_of TYPE('a)) b"
  3460     a = bintrunc (len_of TYPE('a) - n) a \<and> b = bintrunc (len_of TYPE('a)) b"
       
  3461   for w :: "'a::len0 word"
  3475   apply (frule word_ubin.norm_Rep [THEN ssubst])
  3462   apply (frule word_ubin.norm_Rep [THEN ssubst])
  3476   apply (drule bin_split_trunc1)
  3463   apply (drule bin_split_trunc1)
  3477   apply (drule sym [THEN trans])
  3464   apply (drule sym [THEN trans])
  3478   apply assumption
  3465    apply assumption
  3479   apply safe
  3466   apply safe
  3480   done
  3467   done
  3481 
  3468 
  3482 lemma word_split_bl':
  3469 lemma word_split_bl':
  3483   "std = size c - size b \<Longrightarrow> (word_split c = (a, b)) \<Longrightarrow>
  3470   "std = size c - size b \<Longrightarrow> (word_split c = (a, b)) \<Longrightarrow>
  3484     (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c)))"
  3471     (a = of_bl (take std (to_bl c)) \<and> b = of_bl (drop std (to_bl c)))"
  3485   apply (unfold word_split_bin')
  3472   apply (unfold word_split_bin')
  3486   apply safe
  3473   apply safe
  3487    defer
  3474    defer
  3488    apply (clarsimp split: prod.splits)
  3475    apply (clarsimp split: prod.splits)
  3489    apply hypsubst_thin
  3476    apply hypsubst_thin
  3490    apply (drule word_ubin.norm_Rep [THEN ssubst])
  3477    apply (drule word_ubin.norm_Rep [THEN ssubst])
  3491    apply (drule split_bintrunc)
  3478    apply (drule split_bintrunc)
  3492    apply (simp add : of_bl_def bl2bin_drop word_size
  3479    apply (simp add: of_bl_def bl2bin_drop word_size
  3493        word_ubin.norm_eq_iff [symmetric] min_def del : word_ubin.norm_Rep)
  3480       word_ubin.norm_eq_iff [symmetric] min_def del: word_ubin.norm_Rep)
  3494   apply (clarsimp split: prod.splits)
  3481   apply (clarsimp split: prod.splits)
  3495   apply (frule split_uint_lem [THEN conjunct1])
  3482   apply (frule split_uint_lem [THEN conjunct1])
  3496   apply (unfold word_size)
  3483   apply (unfold word_size)
  3497   apply (cases "len_of TYPE('a) >= len_of TYPE('b)")
  3484   apply (cases "len_of TYPE('a) \<ge> len_of TYPE('b)")
  3498    defer
  3485    defer
  3499    apply simp
  3486    apply simp
  3500   apply (simp add : of_bl_def to_bl_def)
  3487   apply (simp add : of_bl_def to_bl_def)
  3501   apply (subst bin_split_take1 [symmetric])
  3488   apply (subst bin_split_take1 [symmetric])
  3502     prefer 2
  3489     prefer 2
  3506   apply (erule arg_cong [THEN trans])
  3493   apply (erule arg_cong [THEN trans])
  3507   apply (simp add : word_ubin.norm_eq_iff [symmetric])
  3494   apply (simp add : word_ubin.norm_eq_iff [symmetric])
  3508   done
  3495   done
  3509 
  3496 
  3510 lemma word_split_bl: "std = size c - size b \<Longrightarrow>
  3497 lemma word_split_bl: "std = size c - size b \<Longrightarrow>
  3511     (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c))) \<longleftrightarrow>
  3498     (a = of_bl (take std (to_bl c)) \<and> b = of_bl (drop std (to_bl c))) \<longleftrightarrow>
  3512     word_split c = (a, b)"
  3499     word_split c = (a, b)"
  3513   apply (rule iffI)
  3500   apply (rule iffI)
  3514    defer
  3501    defer
  3515    apply (erule (1) word_split_bl')
  3502    apply (erule (1) word_split_bl')
  3516   apply (case_tac "word_split c")
  3503   apply (case_tac "word_split c")
  3517   apply (auto simp add : word_size)
  3504   apply (auto simp add: word_size)
  3518   apply (frule word_split_bl' [rotated])
  3505   apply (frule word_split_bl' [rotated])
  3519   apply (auto simp add : word_size)
  3506    apply (auto simp add: word_size)
  3520   done
  3507   done
  3521 
  3508 
  3522 lemma word_split_bl_eq:
  3509 lemma word_split_bl_eq:
  3523    "(word_split (c::'a::len word) :: ('c::len0 word * 'd::len0 word)) =
  3510   "(word_split c :: ('c::len0 word \<times> 'd::len0 word)) =
  3524       (of_bl (take (len_of TYPE('a::len) - len_of TYPE('d::len0)) (to_bl c)),
  3511     (of_bl (take (len_of TYPE('a::len) - len_of TYPE('d::len0)) (to_bl c)),
  3525        of_bl (drop (len_of TYPE('a) - len_of TYPE('d)) (to_bl c)))"
  3512      of_bl (drop (len_of TYPE('a) - len_of TYPE('d)) (to_bl c)))"
       
  3513   for c :: "'a::len word"
  3526   apply (rule word_split_bl [THEN iffD1])
  3514   apply (rule word_split_bl [THEN iffD1])
  3527   apply (unfold word_size)
  3515    apply (unfold word_size)
  3528   apply (rule refl conjI)+
  3516    apply (rule refl conjI)+
  3529   done
  3517   done
  3530 
  3518 
  3531 \<comment> "keep quantifiers for use in simplification"
  3519 \<comment> "keep quantifiers for use in simplification"
  3532 lemma test_bit_split':
  3520 lemma test_bit_split':
  3533   "word_split c = (a, b) --> (ALL n m. b !! n = (n < size b & c !! n) &
  3521   "word_split c = (a, b) \<longrightarrow>
  3534     a !! m = (m < size a & c !! (m + size b)))"
  3522     (\<forall>n m.
       
  3523       b !! n = (n < size b \<and> c !! n) \<and>
       
  3524       a !! m = (m < size a \<and> c !! (m + size b)))"
  3535   apply (unfold word_split_bin' test_bit_bin)
  3525   apply (unfold word_split_bin' test_bit_bin)
  3536   apply (clarify)
  3526   apply (clarify)
  3537   apply (clarsimp simp: word_ubin.eq_norm nth_bintr word_size split: prod.splits)
  3527   apply (clarsimp simp: word_ubin.eq_norm nth_bintr word_size split: prod.splits)
  3538   apply (drule bin_nth_split)
  3528   apply (drule bin_nth_split)
  3539   apply safe
  3529   apply safe
  3541    apply (erule bin_nth_uint_imp)+
  3531    apply (erule bin_nth_uint_imp)+
  3542   done
  3532   done
  3543 
  3533 
  3544 lemma test_bit_split:
  3534 lemma test_bit_split:
  3545   "word_split c = (a, b) \<Longrightarrow>
  3535   "word_split c = (a, b) \<Longrightarrow>
  3546     (\<forall>n::nat. b !! n \<longleftrightarrow> n < size b \<and> c !! n) \<and> (\<forall>m::nat. a !! m \<longleftrightarrow> m < size a \<and> c !! (m + size b))"
  3536     (\<forall>n::nat. b !! n \<longleftrightarrow> n < size b \<and> c !! n) \<and>
       
  3537     (\<forall>m::nat. a !! m \<longleftrightarrow> m < size a \<and> c !! (m + size b))"
  3547   by (simp add: test_bit_split')
  3538   by (simp add: test_bit_split')
  3548 
  3539 
  3549 lemma test_bit_split_eq: "word_split c = (a, b) \<longleftrightarrow>
  3540 lemma test_bit_split_eq:
  3550   ((ALL n::nat. b !! n = (n < size b & c !! n)) &
  3541   "word_split c = (a, b) \<longleftrightarrow>
  3551     (ALL m::nat. a !! m = (m < size a & c !! (m + size b))))"
  3542     ((\<forall>n::nat. b !! n = (n < size b \<and> c !! n)) \<and>
       
  3543      (\<forall>m::nat. a !! m = (m < size a \<and> c !! (m + size b))))"
  3552   apply (rule_tac iffI)
  3544   apply (rule_tac iffI)
  3553    apply (rule_tac conjI)
  3545    apply (rule_tac conjI)
  3554     apply (erule test_bit_split [THEN conjunct1])
  3546     apply (erule test_bit_split [THEN conjunct1])
  3555    apply (erule test_bit_split [THEN conjunct2])
  3547    apply (erule test_bit_split [THEN conjunct2])
  3556   apply (case_tac "word_split c")
  3548   apply (case_tac "word_split c")
  3557   apply (frule test_bit_split)
  3549   apply (frule test_bit_split)
  3558   apply (erule trans)
  3550   apply (erule trans)
  3559   apply (fastforce intro ! : word_eqI simp add : word_size)
  3551   apply (fastforce intro!: word_eqI simp add: word_size)
  3560   done
  3552   done
  3561 
  3553 
  3562 \<comment> \<open>this odd result is analogous to \<open>ucast_id\<close>,
  3554 \<comment> \<open>this odd result is analogous to \<open>ucast_id\<close>,
  3563       result to the length given by the result type\<close>
  3555       result to the length given by the result type\<close>
  3564 
  3556 
  3565 lemma word_cat_id: "word_cat a b = b"
  3557 lemma word_cat_id: "word_cat a b = b"
  3566   unfolding word_cat_bin' by (simp add: word_ubin.inverse_norm)
  3558   by (simp add: word_cat_bin' word_ubin.inverse_norm)
  3567 
  3559 
  3568 \<comment> "limited hom result"
  3560 \<comment> "limited hom result"
  3569 lemma word_cat_hom:
  3561 lemma word_cat_hom:
  3570   "len_of TYPE('a::len0) <= len_of TYPE('b::len0) + len_of TYPE('c::len0)
  3562   "len_of TYPE('a::len0) \<le> len_of TYPE('b::len0) + len_of TYPE('c::len0) \<Longrightarrow>
  3571   \<Longrightarrow>
  3563     (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) =
  3572   (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) =
  3564     word_of_int (bin_cat w (size b) (uint b))"
  3573   word_of_int (bin_cat w (size b) (uint b))"
  3565   by (auto simp: word_cat_def word_size word_ubin.norm_eq_iff [symmetric]
  3574   apply (unfold word_cat_def word_size)
       
  3575   apply (clarsimp simp add: word_ubin.norm_eq_iff [symmetric]
       
  3576       word_ubin.eq_norm bintr_cat min.absorb1)
  3566       word_ubin.eq_norm bintr_cat min.absorb1)
  3577   done
  3567 
  3578 
  3568 lemma word_cat_split_alt: "size w \<le> size u + size v \<Longrightarrow> word_split w = (u, v) \<Longrightarrow> word_cat u v = w"
  3579 lemma word_cat_split_alt:
       
  3580   "size w <= size u + size v \<Longrightarrow> word_split w = (u, v) \<Longrightarrow> word_cat u v = w"
       
  3581   apply (rule word_eqI)
  3569   apply (rule word_eqI)
  3582   apply (drule test_bit_split)
  3570   apply (drule test_bit_split)
  3583   apply (clarsimp simp add : test_bit_cat word_size)
  3571   apply (clarsimp simp add : test_bit_cat word_size)
  3584   apply safe
  3572   apply safe
  3585   apply arith
  3573   apply arith
  3588 lemmas word_cat_split_size = sym [THEN [2] word_cat_split_alt [symmetric]]
  3576 lemmas word_cat_split_size = sym [THEN [2] word_cat_split_alt [symmetric]]
  3589 
  3577 
  3590 
  3578 
  3591 subsubsection \<open>Split and slice\<close>
  3579 subsubsection \<open>Split and slice\<close>
  3592 
  3580 
  3593 lemma split_slices:
  3581 lemma split_slices: "word_split w = (u, v) \<Longrightarrow> u = slice (size v) w \<and> v = slice 0 w"
  3594   "word_split w = (u, v) \<Longrightarrow> u = slice (size v) w & v = slice 0 w"
       
  3595   apply (drule test_bit_split)
  3582   apply (drule test_bit_split)
  3596   apply (rule conjI)
  3583   apply (rule conjI)
  3597    apply (rule word_eqI, clarsimp simp: nth_slice word_size)+
  3584    apply (rule word_eqI, clarsimp simp: nth_slice word_size)+
  3598   done
  3585   done
  3599 
  3586 
  3615   apply safe
  3602   apply safe
  3616   apply arith
  3603   apply arith
  3617   done
  3604   done
  3618 
  3605 
  3619 lemma word_split_cat_alt:
  3606 lemma word_split_cat_alt:
  3620   "w = word_cat u v \<Longrightarrow> size u + size v <= size w \<Longrightarrow> word_split w = (u, v)"
  3607   "w = word_cat u v \<Longrightarrow> size u + size v \<le> size w \<Longrightarrow> word_split w = (u, v)"
  3621   apply (case_tac "word_split w")
  3608   apply (case_tac "word_split w")
  3622   apply (rule trans, assumption)
  3609   apply (rule trans, assumption)
  3623   apply (drule test_bit_split)
  3610   apply (drule test_bit_split)
  3624   apply safe
  3611   apply safe
  3625    apply (rule word_eqI, clarsimp simp: test_bit_cat word_size)+
  3612    apply (rule word_eqI, clarsimp simp: test_bit_cat word_size)+
  3626   done
  3613   done
  3627 
  3614 
  3628 lemmas word_cat_bl_no_bin [simp] =
  3615 lemmas word_cat_bl_no_bin [simp] =
  3629   word_cat_bl [where a="numeral a" and b="numeral b",
  3616   word_cat_bl [where a="numeral a" and b="numeral b", unfolded to_bl_numeral]
  3630     unfolded to_bl_numeral]
       
  3631   for a b (* FIXME: negative numerals, 0 and 1 *)
  3617   for a b (* FIXME: negative numerals, 0 and 1 *)
  3632 
  3618 
  3633 lemmas word_split_bl_no_bin [simp] =
  3619 lemmas word_split_bl_no_bin [simp] =
  3634   word_split_bl_eq [where c="numeral c", unfolded to_bl_numeral] for c
  3620   word_split_bl_eq [where c="numeral c", unfolded to_bl_numeral] for c
  3635 
  3621 
  3636 text \<open>this odd result arises from the fact that the statement of the
  3622 text \<open>
  3637       result implies that the decoded words are of the same type,
  3623   This odd result arises from the fact that the statement of the
  3638       and therefore of the same length, as the original word\<close>
  3624   result implies that the decoded words are of the same type,
       
  3625   and therefore of the same length, as the original word.\<close>
  3639 
  3626 
  3640 lemma word_rsplit_same: "word_rsplit w = [w]"
  3627 lemma word_rsplit_same: "word_rsplit w = [w]"
  3641   unfolding word_rsplit_def by (simp add : bin_rsplit_all)
  3628   by (simp add: word_rsplit_def bin_rsplit_all)
  3642 
  3629 
  3643 lemma word_rsplit_empty_iff_size:
  3630 lemma word_rsplit_empty_iff_size: "word_rsplit w = [] \<longleftrightarrow> size w = 0"
  3644   "(word_rsplit w = []) = (size w = 0)"
  3631   by (simp add: word_rsplit_def bin_rsplit_def word_size bin_rsplit_aux_simp_alt Let_def
  3645   unfolding word_rsplit_def bin_rsplit_def word_size
  3632       split: prod.split)
  3646   by (simp add: bin_rsplit_aux_simp_alt Let_def split: prod.split)
       
  3647 
  3633 
  3648 lemma test_bit_rsplit:
  3634 lemma test_bit_rsplit:
  3649   "sw = word_rsplit w \<Longrightarrow> m < size (hd sw :: 'a::len word) \<Longrightarrow>
  3635   "sw = word_rsplit w \<Longrightarrow> m < size (hd sw :: 'a::len word) \<Longrightarrow>
  3650     k < length sw \<Longrightarrow> (rev sw ! k) !! m = (w !! (k * size (hd sw) + m))"
  3636     k < length sw \<Longrightarrow> (rev sw ! k) !! m = (w !! (k * size (hd sw) + m))"
  3651   apply (unfold word_rsplit_def word_test_bit_def)
  3637   apply (unfold word_rsplit_def word_test_bit_def)
  3652   apply (rule trans)
  3638   apply (rule trans)
  3653    apply (rule_tac f = "%x. bin_nth x m" in arg_cong)
  3639    apply (rule_tac f = "\<lambda>x. bin_nth x m" in arg_cong)
  3654    apply (rule nth_map [symmetric])
  3640    apply (rule nth_map [symmetric])
  3655    apply simp
  3641    apply simp
  3656   apply (rule bin_nth_rsplit)
  3642   apply (rule bin_nth_rsplit)
  3657      apply simp_all
  3643      apply simp_all
  3658   apply (simp add : word_size rev_map)
  3644   apply (simp add : word_size rev_map)
  3663   apply (simp add : word_ubin.eq_norm)
  3649   apply (simp add : word_ubin.eq_norm)
  3664   apply (erule bin_rsplit_size_sign [OF len_gt_0 refl])
  3650   apply (erule bin_rsplit_size_sign [OF len_gt_0 refl])
  3665   done
  3651   done
  3666 
  3652 
  3667 lemma word_rcat_bl: "word_rcat wl = of_bl (concat (map to_bl wl))"
  3653 lemma word_rcat_bl: "word_rcat wl = of_bl (concat (map to_bl wl))"
  3668   unfolding word_rcat_def to_bl_def' of_bl_def
  3654   by (auto simp: word_rcat_def to_bl_def' of_bl_def bin_rcat_bl)
  3669   by (clarsimp simp add : bin_rcat_bl)
  3655 
  3670 
  3656 lemma size_rcat_lem': "size (concat (map to_bl wl)) = length wl * size (hd wl)"
  3671 lemma size_rcat_lem':
  3657   by (induct wl) (auto simp: word_size)
  3672   "size (concat (map to_bl wl)) = length wl * size (hd wl)"
       
  3673   unfolding word_size by (induct wl) auto
       
  3674 
  3658 
  3675 lemmas size_rcat_lem = size_rcat_lem' [unfolded word_size]
  3659 lemmas size_rcat_lem = size_rcat_lem' [unfolded word_size]
  3676 
  3660 
  3677 lemmas td_gal_lt_len = len_gt_0 [THEN td_gal_lt]
  3661 lemmas td_gal_lt_len = len_gt_0 [THEN td_gal_lt]
  3678 
  3662 
  3679 lemma nth_rcat_lem:
  3663 lemma nth_rcat_lem:
  3680   "n < length (wl::'a word list) * len_of TYPE('a::len) \<Longrightarrow>
  3664   "n < length (wl::'a word list) * len_of TYPE('a::len) \<Longrightarrow>
  3681     rev (concat (map to_bl wl)) ! n =
  3665     rev (concat (map to_bl wl)) ! n =
  3682     rev (to_bl (rev wl ! (n div len_of TYPE('a)))) ! (n mod len_of TYPE('a))"
  3666     rev (to_bl (rev wl ! (n div len_of TYPE('a)))) ! (n mod len_of TYPE('a))"
  3683   apply (induct "wl")
  3667   apply (induct wl)
  3684    apply clarsimp
  3668    apply clarsimp
  3685   apply (clarsimp simp add : nth_append size_rcat_lem)
  3669   apply (clarsimp simp add : nth_append size_rcat_lem)
  3686   apply (simp (no_asm_use) only:  mult_Suc [symmetric]
  3670   apply (simp (no_asm_use) only:  mult_Suc [symmetric]
  3687          td_gal_lt_len less_Suc_eq_le minus_div_mult_eq_mod [symmetric])
  3671          td_gal_lt_len less_Suc_eq_le minus_div_mult_eq_mod [symmetric])
  3688   apply clarsimp
  3672   apply clarsimp
  3689   done
  3673   done
  3690 
  3674 
  3691 lemma test_bit_rcat:
  3675 lemma test_bit_rcat:
  3692   "sw = size (hd wl :: 'a::len word) \<Longrightarrow> rc = word_rcat wl \<Longrightarrow> rc !! n =
  3676   "sw = size (hd wl :: 'a::len word) \<Longrightarrow> rc = word_rcat wl \<Longrightarrow> rc !! n =
  3693     (n < size rc & n div sw < size wl & (rev wl) ! (n div sw) !! (n mod sw))"
  3677     (n < size rc \<and> n div sw < size wl \<and> (rev wl) ! (n div sw) !! (n mod sw))"
  3694   apply (unfold word_rcat_bl word_size)
  3678   apply (unfold word_rcat_bl word_size)
  3695   apply (clarsimp simp add :
  3679   apply (clarsimp simp add: test_bit_of_bl size_rcat_lem word_size td_gal_lt_len)
  3696     test_bit_of_bl size_rcat_lem word_size td_gal_lt_len)
       
  3697   apply safe
  3680   apply safe
  3698    apply (auto simp add :
  3681    apply (auto simp: test_bit_bl word_size td_gal_lt_len [THEN iffD2, THEN nth_rcat_lem])
  3699     test_bit_bl word_size td_gal_lt_len [THEN iffD2, THEN nth_rcat_lem])
  3682   done
  3700   done
  3683 
  3701 
  3684 lemma foldl_eq_foldr: "foldl op + x xs = foldr op + (x # xs) 0"
  3702 lemma foldl_eq_foldr:
  3685   for x :: "'a::comm_monoid_add"
  3703   "foldl op + x xs = foldr op + (x # xs) (0 :: 'a :: comm_monoid_add)"
  3686   by (induct xs arbitrary: x) (auto simp: add.assoc)
  3704   by (induct xs arbitrary: x) (auto simp add : add.assoc)
       
  3705 
  3687 
  3706 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong]
  3688 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong]
  3707 
  3689 
  3708 lemmas test_bit_rsplit_alt =
  3690 lemmas test_bit_rsplit_alt =
  3709   trans [OF nth_rev_alt [THEN test_bit_cong]
  3691   trans [OF nth_rev_alt [THEN test_bit_cong]
  3711 
  3693 
  3712 \<comment> "lazy way of expressing that u and v, and su and sv, have same types"
  3694 \<comment> "lazy way of expressing that u and v, and su and sv, have same types"
  3713 lemma word_rsplit_len_indep [OF refl refl refl refl]:
  3695 lemma word_rsplit_len_indep [OF refl refl refl refl]:
  3714   "[u,v] = p \<Longrightarrow> [su,sv] = q \<Longrightarrow> word_rsplit u = su \<Longrightarrow>
  3696   "[u,v] = p \<Longrightarrow> [su,sv] = q \<Longrightarrow> word_rsplit u = su \<Longrightarrow>
  3715     word_rsplit v = sv \<Longrightarrow> length su = length sv"
  3697     word_rsplit v = sv \<Longrightarrow> length su = length sv"
  3716   apply (unfold word_rsplit_def)
  3698   by (auto simp: word_rsplit_def bin_rsplit_len_indep)
  3717   apply (auto simp add : bin_rsplit_len_indep)
       
  3718   done
       
  3719 
  3699 
  3720 lemma length_word_rsplit_size:
  3700 lemma length_word_rsplit_size:
  3721   "n = len_of TYPE('a::len) \<Longrightarrow>
  3701   "n = len_of TYPE('a::len) \<Longrightarrow>
  3722     (length (word_rsplit w :: 'a word list) <= m) = (size w <= m * n)"
  3702     length (word_rsplit w :: 'a word list) \<le> m \<longleftrightarrow> size w \<le> m * n"
  3723   apply (unfold word_rsplit_def word_size)
  3703   by (auto simp: word_rsplit_def word_size bin_rsplit_len_le)
  3724   apply (clarsimp simp add : bin_rsplit_len_le)
       
  3725   done
       
  3726 
  3704 
  3727 lemmas length_word_rsplit_lt_size =
  3705 lemmas length_word_rsplit_lt_size =
  3728   length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]]
  3706   length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]]
  3729 
  3707 
  3730 lemma length_word_rsplit_exp_size:
  3708 lemma length_word_rsplit_exp_size:
  3731   "n = len_of TYPE('a::len) \<Longrightarrow>
  3709   "n = len_of TYPE('a::len) \<Longrightarrow>
  3732     length (word_rsplit w :: 'a word list) = (size w + n - 1) div n"
  3710     length (word_rsplit w :: 'a word list) = (size w + n - 1) div n"
  3733   unfolding word_rsplit_def by (clarsimp simp add : word_size bin_rsplit_len)
  3711   by (auto simp: word_rsplit_def word_size bin_rsplit_len)
  3734 
  3712 
  3735 lemma length_word_rsplit_even_size:
  3713 lemma length_word_rsplit_even_size:
  3736   "n = len_of TYPE('a::len) \<Longrightarrow> size w = m * n \<Longrightarrow>
  3714   "n = len_of TYPE('a::len) \<Longrightarrow> size w = m * n \<Longrightarrow>
  3737     length (word_rsplit w :: 'a word list) = m"
  3715     length (word_rsplit w :: 'a word list) = m"
  3738   by (clarsimp simp add : length_word_rsplit_exp_size given_quot_alt)
  3716   by (auto simp: length_word_rsplit_exp_size given_quot_alt)
  3739 
  3717 
  3740 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size]
  3718 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size]
  3741 
  3719 
  3742 (* alternative proof of word_rcat_rsplit *)
  3720 (* alternative proof of word_rcat_rsplit *)
  3743 lemmas tdle = iffD2 [OF split_div_lemma refl, THEN conjunct1]
  3721 lemmas tdle = iffD2 [OF split_div_lemma refl, THEN conjunct1]
  3744 lemmas dtle = xtr4 [OF tdle mult.commute]
  3722 lemmas dtle = xtr4 [OF tdle mult.commute]
  3745 
  3723 
  3746 lemma word_rcat_rsplit: "word_rcat (word_rsplit w) = w"
  3724 lemma word_rcat_rsplit: "word_rcat (word_rsplit w) = w"
  3747   apply (rule word_eqI)
  3725   apply (rule word_eqI)
  3748   apply (clarsimp simp add : test_bit_rcat word_size)
  3726   apply (clarsimp simp: test_bit_rcat word_size)
  3749   apply (subst refl [THEN test_bit_rsplit])
  3727   apply (subst refl [THEN test_bit_rsplit])
  3750     apply (simp_all add: word_size
  3728     apply (simp_all add: word_size
  3751       refl [THEN length_word_rsplit_size [simplified not_less [symmetric], simplified]])
  3729       refl [THEN length_word_rsplit_size [simplified not_less [symmetric], simplified]])
  3752    apply safe
  3730    apply safe
  3753    apply (erule xtr7, rule len_gt_0 [THEN dtle])+
  3731    apply (erule xtr7, rule len_gt_0 [THEN dtle])+
  3754   done
  3732   done
  3755 
  3733 
  3756 lemma size_word_rsplit_rcat_size:
  3734 lemma size_word_rsplit_rcat_size:
  3757   "\<lbrakk>word_rcat (ws::'a::len word list) = (frcw::'b::len0 word);
  3735   "word_rcat ws = frcw \<Longrightarrow> size frcw = length ws * len_of TYPE('a)
  3758      size frcw = length ws * len_of TYPE('a)\<rbrakk>
       
  3759     \<Longrightarrow> length (word_rsplit frcw::'a word list) = length ws"
  3736     \<Longrightarrow> length (word_rsplit frcw::'a word list) = length ws"
  3760   apply (clarsimp simp add : word_size length_word_rsplit_exp_size')
  3737   for ws :: "'a::len word list" and frcw :: "'b::len0 word"
       
  3738   apply (clarsimp simp: word_size length_word_rsplit_exp_size')
  3761   apply (fast intro: given_quot_alt)
  3739   apply (fast intro: given_quot_alt)
  3762   done
  3740   done
  3763 
  3741 
  3764 lemma msrevs:
  3742 lemma msrevs:
  3765   fixes n::nat
  3743   "0 < n \<Longrightarrow> (k * n + m) div n = m div n + k"
  3766   shows "0 < n \<Longrightarrow> (k * n + m) div n = m div n + k"
  3744   "(k * n + m) mod n = m mod n"
  3767   and   "(k * n + m) mod n = m mod n"
  3745   for n :: nat
  3768   by (auto simp: add.commute)
  3746   by (auto simp: add.commute)
  3769 
  3747 
  3770 lemma word_rsplit_rcat_size [OF refl]:
  3748 lemma word_rsplit_rcat_size [OF refl]:
  3771   "word_rcat (ws :: 'a::len word list) = frcw \<Longrightarrow>
  3749   "word_rcat ws = frcw \<Longrightarrow>
  3772     size frcw = length ws * len_of TYPE('a) \<Longrightarrow> word_rsplit frcw = ws"
  3750     size frcw = length ws * len_of TYPE('a) \<Longrightarrow> word_rsplit frcw = ws"
       
  3751   for ws :: "'a::len word list"
  3773   apply (frule size_word_rsplit_rcat_size, assumption)
  3752   apply (frule size_word_rsplit_rcat_size, assumption)
  3774   apply (clarsimp simp add : word_size)
  3753   apply (clarsimp simp add : word_size)
  3775   apply (rule nth_equalityI, assumption)
  3754   apply (rule nth_equalityI, assumption)
  3776   apply clarsimp
  3755   apply clarsimp
  3777   apply (rule word_eqI [rule_format])
  3756   apply (rule word_eqI [rule_format])
  3778   apply (rule trans)
  3757   apply (rule trans)
  3779    apply (rule test_bit_rsplit_alt)
  3758    apply (rule test_bit_rsplit_alt)
  3780      apply (clarsimp simp: word_size)+
  3759      apply (clarsimp simp: word_size)+
  3781   apply (rule trans)
  3760   apply (rule trans)
  3782   apply (rule test_bit_rcat [OF refl refl])
  3761    apply (rule test_bit_rcat [OF refl refl])
  3783   apply (simp add: word_size)
  3762   apply (simp add: word_size)
  3784   apply (subst nth_rev)
  3763   apply (subst nth_rev)
  3785    apply arith
  3764    apply arith
  3786   apply (simp add: le0 [THEN [2] xtr7, THEN diff_Suc_less])
  3765   apply (simp add: le0 [THEN [2] xtr7, THEN diff_Suc_less])
  3787   apply safe
  3766   apply safe
  3788   apply (simp add: diff_mult_distrib)
  3767   apply (simp add: diff_mult_distrib)
  3789   apply (rule mpl_lem)
  3768   apply (rule mpl_lem)
  3790   apply (cases "size ws")
  3769    apply (cases "size ws")
  3791    apply simp_all
  3770     apply simp_all
  3792   done
  3771   done
  3793 
  3772 
  3794 
  3773 
  3795 subsection \<open>Rotation\<close>
  3774 subsection \<open>Rotation\<close>
  3796 
  3775 
  3797 lemmas rotater_0' [simp] = rotater_def [where n = "0", simplified]
  3776 lemmas rotater_0' [simp] = rotater_def [where n = "0", simplified]
  3798 
  3777 
  3799 lemmas word_rot_defs = word_roti_def word_rotr_def word_rotl_def
  3778 lemmas word_rot_defs = word_roti_def word_rotr_def word_rotl_def
  3800 
  3779 
  3801 lemma rotate_eq_mod:
  3780 lemma rotate_eq_mod: "m mod length xs = n mod length xs \<Longrightarrow> rotate m xs = rotate n xs"
  3802   "m mod length xs = n mod length xs \<Longrightarrow> rotate m xs = rotate n xs"
       
  3803   apply (rule box_equals)
  3781   apply (rule box_equals)
  3804     defer
  3782     defer
  3805     apply (rule rotate_conv_mod [symmetric])+
  3783     apply (rule rotate_conv_mod [symmetric])+
  3806   apply simp
  3784   apply simp
  3807   done
  3785   done
  3815 
  3793 
  3816 
  3794 
  3817 subsubsection \<open>Rotation of list to right\<close>
  3795 subsubsection \<open>Rotation of list to right\<close>
  3818 
  3796 
  3819 lemma rotate1_rl': "rotater1 (l @ [a]) = a # l"
  3797 lemma rotate1_rl': "rotater1 (l @ [a]) = a # l"
  3820   unfolding rotater1_def by (cases l) auto
  3798   by (cases l) (auto simp: rotater1_def)
  3821 
  3799 
  3822 lemma rotate1_rl [simp] : "rotater1 (rotate1 l) = l"
  3800 lemma rotate1_rl [simp] : "rotater1 (rotate1 l) = l"
  3823   apply (unfold rotater1_def)
  3801   apply (unfold rotater1_def)
  3824   apply (cases "l")
  3802   apply (cases "l")
  3825   apply (case_tac [2] "list")
  3803    apply (case_tac [2] "list")
  3826   apply auto
  3804     apply auto
  3827   done
  3805   done
  3828 
  3806 
  3829 lemma rotate1_lr [simp] : "rotate1 (rotater1 l) = l"
  3807 lemma rotate1_lr [simp] : "rotate1 (rotater1 l) = l"
  3830   unfolding rotater1_def by (cases l) auto
  3808   by (cases l) (auto simp: rotater1_def)
  3831 
  3809 
  3832 lemma rotater1_rev': "rotater1 (rev xs) = rev (rotate1 xs)"
  3810 lemma rotater1_rev': "rotater1 (rev xs) = rev (rotate1 xs)"
  3833   apply (cases "xs")
  3811   by (cases "xs") (simp add: rotater1_def, simp add: rotate1_rl')
  3834   apply (simp add : rotater1_def)
       
  3835   apply (simp add : rotate1_rl')
       
  3836   done
       
  3837 
  3812 
  3838 lemma rotater_rev': "rotater n (rev xs) = rev (rotate n xs)"
  3813 lemma rotater_rev': "rotater n (rev xs) = rev (rotate n xs)"
  3839   unfolding rotater_def by (induct n) (auto intro: rotater1_rev')
  3814   by (induct n) (auto simp: rotater_def intro: rotater1_rev')
  3840 
  3815 
  3841 lemma rotater_rev: "rotater n ys = rev (rotate n (rev ys))"
  3816 lemma rotater_rev: "rotater n ys = rev (rotate n (rev ys))"
  3842   using rotater_rev' [where xs = "rev ys"] by simp
  3817   using rotater_rev' [where xs = "rev ys"] by simp
  3843 
  3818 
  3844 lemma rotater_drop_take:
  3819 lemma rotater_drop_take:
  3845   "rotater n xs =
  3820   "rotater n xs =
  3846    drop (length xs - n mod length xs) xs @
  3821     drop (length xs - n mod length xs) xs @
  3847    take (length xs - n mod length xs) xs"
  3822     take (length xs - n mod length xs) xs"
  3848   by (clarsimp simp add : rotater_rev rotate_drop_take rev_take rev_drop)
  3823   by (auto simp: rotater_rev rotate_drop_take rev_take rev_drop)
  3849 
  3824 
  3850 lemma rotater_Suc [simp] :
  3825 lemma rotater_Suc [simp]: "rotater (Suc n) xs = rotater1 (rotater n xs)"
  3851   "rotater (Suc n) xs = rotater1 (rotater n xs)"
       
  3852   unfolding rotater_def by auto
  3826   unfolding rotater_def by auto
  3853 
  3827 
  3854 lemma rotate_inv_plus [rule_format] :
  3828 lemma rotate_inv_plus [rule_format] :
  3855   "ALL k. k = m + n --> rotater k (rotate n xs) = rotater m xs &
  3829   "\<forall>k. k = m + n \<longrightarrow> rotater k (rotate n xs) = rotater m xs \<and>
  3856     rotate k (rotater n xs) = rotate m xs &
  3830     rotate k (rotater n xs) = rotate m xs \<and>
  3857     rotater n (rotate k xs) = rotate m xs &
  3831     rotater n (rotate k xs) = rotate m xs \<and>
  3858     rotate n (rotater k xs) = rotater m xs"
  3832     rotate n (rotater k xs) = rotater m xs"
  3859   unfolding rotater_def rotate_def
  3833   by (induct n) (auto simp: rotater_def rotate_def intro: funpow_swap1 [THEN trans])
  3860   by (induct n) (auto intro: funpow_swap1 [THEN trans])
       
  3861 
  3834 
  3862 lemmas rotate_inv_rel = le_add_diff_inverse2 [symmetric, THEN rotate_inv_plus]
  3835 lemmas rotate_inv_rel = le_add_diff_inverse2 [symmetric, THEN rotate_inv_plus]
  3863 
  3836 
  3864 lemmas rotate_inv_eq = order_refl [THEN rotate_inv_rel, simplified]
  3837 lemmas rotate_inv_eq = order_refl [THEN rotate_inv_rel, simplified]
  3865 
  3838 
  3866 lemmas rotate_lr [simp] = rotate_inv_eq [THEN conjunct1]
  3839 lemmas rotate_lr [simp] = rotate_inv_eq [THEN conjunct1]
  3867 lemmas rotate_rl [simp] = rotate_inv_eq [THEN conjunct2, THEN conjunct1]
  3840 lemmas rotate_rl [simp] = rotate_inv_eq [THEN conjunct2, THEN conjunct1]
  3868 
  3841 
  3869 lemma rotate_gal: "(rotater n xs = ys) = (rotate n ys = xs)"
  3842 lemma rotate_gal: "rotater n xs = ys \<longleftrightarrow> rotate n ys = xs"
  3870   by auto
  3843   by auto
  3871 
  3844 
  3872 lemma rotate_gal': "(ys = rotater n xs) = (xs = rotate n ys)"
  3845 lemma rotate_gal': "ys = rotater n xs \<longleftrightarrow> xs = rotate n ys"
  3873   by auto
  3846   by auto
  3874 
  3847 
  3875 lemma length_rotater [simp]:
  3848 lemma length_rotater [simp]: "length (rotater n xs) = length xs"
  3876   "length (rotater n xs) = length xs"
       
  3877   by (simp add : rotater_rev)
  3849   by (simp add : rotater_rev)
  3878 
  3850 
  3879 lemma restrict_to_left:
  3851 lemma restrict_to_left: "x = y \<Longrightarrow> x = z \<longleftrightarrow> y = z"
  3880   assumes "x = y"
  3852   by simp
  3881   shows "(x = z) = (y = z)"
       
  3882   using assms by simp
       
  3883 
  3853 
  3884 lemmas rrs0 = rotate_eqs [THEN restrict_to_left,
  3854 lemmas rrs0 = rotate_eqs [THEN restrict_to_left,
  3885   simplified rotate_gal [symmetric] rotate_gal' [symmetric]]
  3855   simplified rotate_gal [symmetric] rotate_gal' [symmetric]]
  3886 lemmas rrs1 = rrs0 [THEN refl [THEN rev_iffD1]]
  3856 lemmas rrs1 = rrs0 [THEN refl [THEN rev_iffD1]]
  3887 lemmas rotater_eqs = rrs1 [simplified length_rotater]
  3857 lemmas rotater_eqs = rrs1 [simplified length_rotater]
  3889 lemmas rotater_add = rotater_eqs (2)
  3859 lemmas rotater_add = rotater_eqs (2)
  3890 
  3860 
  3891 
  3861 
  3892 subsubsection \<open>map, map2, commuting with rotate(r)\<close>
  3862 subsubsection \<open>map, map2, commuting with rotate(r)\<close>
  3893 
  3863 
  3894 lemma butlast_map:
  3864 lemma butlast_map: "xs \<noteq> [] \<Longrightarrow> butlast (map f xs) = map f (butlast xs)"
  3895   "xs ~= [] \<Longrightarrow> butlast (map f xs) = map f (butlast xs)"
       
  3896   by (induct xs) auto
  3865   by (induct xs) auto
  3897 
  3866 
  3898 lemma rotater1_map: "rotater1 (map f xs) = map f (rotater1 xs)"
  3867 lemma rotater1_map: "rotater1 (map f xs) = map f (rotater1 xs)"
  3899   unfolding rotater1_def
  3868   by (cases xs) (auto simp: rotater1_def last_map butlast_map)
  3900   by (cases xs) (auto simp add: last_map butlast_map)
  3869 
  3901 
  3870 lemma rotater_map: "rotater n (map f xs) = map f (rotater n xs)"
  3902 lemma rotater_map:
  3871   by (induct n) (auto simp: rotater_def rotater1_map)
  3903   "rotater n (map f xs) = map f (rotater n xs)"
       
  3904   unfolding rotater_def
       
  3905   by (induct n) (auto simp add : rotater1_map)
       
  3906 
  3872 
  3907 lemma but_last_zip [rule_format] :
  3873 lemma but_last_zip [rule_format] :
  3908   "ALL ys. length xs = length ys --> xs ~= [] -->
  3874   "\<forall>ys. length xs = length ys \<longrightarrow> xs \<noteq> [] \<longrightarrow>
  3909     last (zip xs ys) = (last xs, last ys) &
  3875     last (zip xs ys) = (last xs, last ys) \<and>
  3910     butlast (zip xs ys) = zip (butlast xs) (butlast ys)"
  3876     butlast (zip xs ys) = zip (butlast xs) (butlast ys)"
  3911   apply (induct "xs")
  3877   apply (induct xs)
  3912   apply auto
  3878    apply auto
  3913      apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
  3879      apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
  3914   done
  3880   done
  3915 
  3881 
  3916 lemma but_last_map2 [rule_format] :
  3882 lemma but_last_map2 [rule_format] :
  3917   "ALL ys. length xs = length ys --> xs ~= [] -->
  3883   "\<forall>ys. length xs = length ys \<longrightarrow> xs \<noteq> [] \<longrightarrow>
  3918     last (map2 f xs ys) = f (last xs) (last ys) &
  3884     last (map2 f xs ys) = f (last xs) (last ys) \<and>
  3919     butlast (map2 f xs ys) = map2 f (butlast xs) (butlast ys)"
  3885     butlast (map2 f xs ys) = map2 f (butlast xs) (butlast ys)"
  3920   apply (induct "xs")
  3886   apply (induct xs)
  3921   apply auto
  3887    apply auto
  3922      apply (unfold map2_def)
  3888      apply (unfold map2_def)
  3923      apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
  3889      apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
  3924   done
  3890   done
  3925 
  3891 
  3926 lemma rotater1_zip:
  3892 lemma rotater1_zip:
  3927   "length xs = length ys \<Longrightarrow>
  3893   "length xs = length ys \<Longrightarrow>
  3928     rotater1 (zip xs ys) = zip (rotater1 xs) (rotater1 ys)"
  3894     rotater1 (zip xs ys) = zip (rotater1 xs) (rotater1 ys)"
  3929   apply (unfold rotater1_def)
  3895   apply (unfold rotater1_def)
  3930   apply (cases "xs")
  3896   apply (cases xs)
  3931    apply auto
  3897    apply auto
  3932    apply ((case_tac ys, auto simp: neq_Nil_conv but_last_zip)[1])+
  3898    apply ((case_tac ys, auto simp: neq_Nil_conv but_last_zip)[1])+
  3933   done
  3899   done
  3934 
  3900 
  3935 lemma rotater1_map2:
  3901 lemma rotater1_map2:
  3936   "length xs = length ys \<Longrightarrow>
  3902   "length xs = length ys \<Longrightarrow>
  3937     rotater1 (map2 f xs ys) = map2 f (rotater1 xs) (rotater1 ys)"
  3903     rotater1 (map2 f xs ys) = map2 f (rotater1 xs) (rotater1 ys)"
  3938   unfolding map2_def by (simp add: rotater1_map rotater1_zip)
  3904   by (simp add: map2_def rotater1_map rotater1_zip)
  3939 
  3905 
  3940 lemmas lrth =
  3906 lemmas lrth =
  3941   box_equals [OF asm_rl length_rotater [symmetric]
  3907   box_equals [OF asm_rl length_rotater [symmetric]
  3942                  length_rotater [symmetric],
  3908                  length_rotater [symmetric],
  3943               THEN rotater1_map2]
  3909               THEN rotater1_map2]
  3948   by (induct n) (auto intro!: lrth)
  3914   by (induct n) (auto intro!: lrth)
  3949 
  3915 
  3950 lemma rotate1_map2:
  3916 lemma rotate1_map2:
  3951   "length xs = length ys \<Longrightarrow>
  3917   "length xs = length ys \<Longrightarrow>
  3952     rotate1 (map2 f xs ys) = map2 f (rotate1 xs) (rotate1 ys)"
  3918     rotate1 (map2 f xs ys) = map2 f (rotate1 xs) (rotate1 ys)"
  3953   apply (unfold map2_def)
  3919   by (cases xs; cases ys) (auto simp: map2_def)
  3954   apply (cases xs)
       
  3955    apply (cases ys, auto)+
       
  3956   done
       
  3957 
  3920 
  3958 lemmas lth = box_equals [OF asm_rl length_rotate [symmetric]
  3921 lemmas lth = box_equals [OF asm_rl length_rotate [symmetric]
  3959   length_rotate [symmetric], THEN rotate1_map2]
  3922   length_rotate [symmetric], THEN rotate1_map2]
  3960 
  3923 
  3961 lemma rotate_map2:
  3924 lemma rotate_map2:
  3964   by (induct n) (auto intro!: lth)
  3927   by (induct n) (auto intro!: lth)
  3965 
  3928 
  3966 
  3929 
  3967 \<comment> "corresponding equalities for word rotation"
  3930 \<comment> "corresponding equalities for word rotation"
  3968 
  3931 
  3969 lemma to_bl_rotl:
  3932 lemma to_bl_rotl: "to_bl (word_rotl n w) = rotate n (to_bl w)"
  3970   "to_bl (word_rotl n w) = rotate n (to_bl w)"
       
  3971   by (simp add: word_bl.Abs_inverse' word_rotl_def)
  3933   by (simp add: word_bl.Abs_inverse' word_rotl_def)
  3972 
  3934 
  3973 lemmas blrs0 = rotate_eqs [THEN to_bl_rotl [THEN trans]]
  3935 lemmas blrs0 = rotate_eqs [THEN to_bl_rotl [THEN trans]]
  3974 
  3936 
  3975 lemmas word_rotl_eqs =
  3937 lemmas word_rotl_eqs =
  3976   blrs0 [simplified word_bl_Rep' word_bl.Rep_inject to_bl_rotl [symmetric]]
  3938   blrs0 [simplified word_bl_Rep' word_bl.Rep_inject to_bl_rotl [symmetric]]
  3977 
  3939 
  3978 lemma to_bl_rotr:
  3940 lemma to_bl_rotr: "to_bl (word_rotr n w) = rotater n (to_bl w)"
  3979   "to_bl (word_rotr n w) = rotater n (to_bl w)"
       
  3980   by (simp add: word_bl.Abs_inverse' word_rotr_def)
  3941   by (simp add: word_bl.Abs_inverse' word_rotr_def)
  3981 
  3942 
  3982 lemmas brrs0 = rotater_eqs [THEN to_bl_rotr [THEN trans]]
  3943 lemmas brrs0 = rotater_eqs [THEN to_bl_rotr [THEN trans]]
  3983 
  3944 
  3984 lemmas word_rotr_eqs =
  3945 lemmas word_rotr_eqs =
  3985   brrs0 [simplified word_bl_Rep' word_bl.Rep_inject to_bl_rotr [symmetric]]
  3946   brrs0 [simplified word_bl_Rep' word_bl.Rep_inject to_bl_rotr [symmetric]]
  3986 
  3947 
  3987 declare word_rotr_eqs (1) [simp]
  3948 declare word_rotr_eqs (1) [simp]
  3988 declare word_rotl_eqs (1) [simp]
  3949 declare word_rotl_eqs (1) [simp]
  3989 
  3950 
  3990 lemma
  3951 lemma word_rot_rl [simp]: "word_rotl k (word_rotr k v) = v"
  3991   word_rot_rl [simp]:
  3952   and word_rot_lr [simp]: "word_rotr k (word_rotl k v) = v"
  3992   "word_rotl k (word_rotr k v) = v" and
       
  3993   word_rot_lr [simp]:
       
  3994   "word_rotr k (word_rotl k v) = v"
       
  3995   by (auto simp add: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric])
  3953   by (auto simp add: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric])
  3996 
  3954 
  3997 lemma
  3955 lemma word_rot_gal: "word_rotr n v = w \<longleftrightarrow> word_rotl n w = v"
  3998   word_rot_gal:
  3956   and word_rot_gal': "w = word_rotr n v \<longleftrightarrow> v = word_rotl n w"
  3999   "(word_rotr n v = w) = (word_rotl n w = v)" and
  3957   by (auto simp: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric] dest: sym)
  4000   word_rot_gal':
  3958 
  4001   "(w = word_rotr n v) = (v = word_rotl n w)"
  3959 lemma word_rotr_rev: "word_rotr n w = word_reverse (word_rotl n (word_reverse w))"
  4002   by (auto simp: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric]
  3960   by (simp only: word_bl.Rep_inject [symmetric] to_bl_word_rev to_bl_rotr to_bl_rotl rotater_rev)
  4003            dest: sym)
       
  4004 
       
  4005 lemma word_rotr_rev:
       
  4006   "word_rotr n w = word_reverse (word_rotl n (word_reverse w))"
       
  4007   by (simp only: word_bl.Rep_inject [symmetric] to_bl_word_rev
       
  4008                 to_bl_rotr to_bl_rotl rotater_rev)
       
  4009 
  3961 
  4010 lemma word_roti_0 [simp]: "word_roti 0 w = w"
  3962 lemma word_roti_0 [simp]: "word_roti 0 w = w"
  4011   by (unfold word_rot_defs) auto
  3963   by (auto simp: word_rot_defs)
  4012 
  3964 
  4013 lemmas abl_cong = arg_cong [where f = "of_bl"]
  3965 lemmas abl_cong = arg_cong [where f = "of_bl"]
  4014 
  3966 
  4015 lemma word_roti_add:
  3967 lemma word_roti_add: "word_roti (m + n) w = word_roti m (word_roti n w)"
  4016   "word_roti (m + n) w = word_roti m (word_roti n w)"
       
  4017 proof -
  3968 proof -
  4018   have rotater_eq_lem:
  3969   have rotater_eq_lem: "\<And>m n xs. m = n \<Longrightarrow> rotater m xs = rotater n xs"
  4019     "\<And>m n xs. m = n \<Longrightarrow> rotater m xs = rotater n xs"
       
  4020     by auto
  3970     by auto
  4021 
  3971 
  4022   have rotate_eq_lem:
  3972   have rotate_eq_lem: "\<And>m n xs. m = n \<Longrightarrow> rotate m xs = rotate n xs"
  4023     "\<And>m n xs. m = n \<Longrightarrow> rotate m xs = rotate n xs"
       
  4024     by auto
  3973     by auto
  4025 
  3974 
  4026   note rpts [symmetric] =
  3975   note rpts [symmetric] =
  4027     rotate_inv_plus [THEN conjunct1]
  3976     rotate_inv_plus [THEN conjunct1]
  4028     rotate_inv_plus [THEN conjunct2, THEN conjunct1]
  3977     rotate_inv_plus [THEN conjunct2, THEN conjunct1]
  4031 
  3980 
  4032   note rrp = trans [symmetric, OF rotate_rotate rotate_eq_lem]
  3981   note rrp = trans [symmetric, OF rotate_rotate rotate_eq_lem]
  4033   note rrrp = trans [symmetric, OF rotater_add [symmetric] rotater_eq_lem]
  3982   note rrrp = trans [symmetric, OF rotater_add [symmetric] rotater_eq_lem]
  4034 
  3983 
  4035   show ?thesis
  3984   show ?thesis
  4036   apply (unfold word_rot_defs)
  3985     apply (unfold word_rot_defs)
  4037   apply (simp only: split: if_split)
  3986     apply (simp only: split: if_split)
  4038   apply (safe intro!: abl_cong)
  3987     apply (safe intro!: abl_cong)
  4039   apply (simp_all only: to_bl_rotl [THEN word_bl.Rep_inverse']
  3988            apply (simp_all only: to_bl_rotl [THEN word_bl.Rep_inverse']
  4040                     to_bl_rotl
  3989                   to_bl_rotl
  4041                     to_bl_rotr [THEN word_bl.Rep_inverse']
  3990                   to_bl_rotr [THEN word_bl.Rep_inverse']
  4042                     to_bl_rotr)
  3991                   to_bl_rotr)
  4043   apply (rule rrp rrrp rpts,
  3992          apply (rule rrp rrrp rpts,
  4044          simp add: nat_add_distrib [symmetric]
  3993                 simp add: nat_add_distrib [symmetric]
  4045                    nat_diff_distrib [symmetric])+
  3994                 nat_diff_distrib [symmetric])+
  4046   done
  3995     done
  4047 qed
  3996 qed
  4048 
  3997 
  4049 lemma word_roti_conv_mod': "word_roti n w = word_roti (n mod int (size w)) w"
  3998 lemma word_roti_conv_mod': "word_roti n w = word_roti (n mod int (size w)) w"
  4050   apply (unfold word_rot_defs)
  3999   apply (unfold word_rot_defs)
  4051   apply (cut_tac y="size w" in gt_or_eq_0)
  4000   apply (cut_tac y="size w" in gt_or_eq_0)
  4127 
  4076 
  4128 lemmas word_rotl_dt = bl_word_rotl_dt [THEN word_bl.Rep_inverse' [symmetric]]
  4077 lemmas word_rotl_dt = bl_word_rotl_dt [THEN word_bl.Rep_inverse' [symmetric]]
  4129 lemmas word_rotr_dt = bl_word_rotr_dt [THEN word_bl.Rep_inverse' [symmetric]]
  4078 lemmas word_rotr_dt = bl_word_rotr_dt [THEN word_bl.Rep_inverse' [symmetric]]
  4130 lemmas word_roti_dt = bl_word_roti_dt [THEN word_bl.Rep_inverse' [symmetric]]
  4079 lemmas word_roti_dt = bl_word_roti_dt [THEN word_bl.Rep_inverse' [symmetric]]
  4131 
  4080 
  4132 lemma word_rotx_0 [simp] : "word_rotr i 0 = 0 & word_rotl i 0 = 0"
  4081 lemma word_rotx_0 [simp] : "word_rotr i 0 = 0 \<and> word_rotl i 0 = 0"
  4133   by (simp add : word_rotr_dt word_rotl_dt replicate_add [symmetric])
  4082   by (simp add: word_rotr_dt word_rotl_dt replicate_add [symmetric])
  4134 
  4083 
  4135 lemma word_roti_0' [simp] : "word_roti n 0 = 0"
  4084 lemma word_roti_0' [simp] : "word_roti n 0 = 0"
  4136   unfolding word_roti_def by auto
  4085   by (auto simp: word_roti_def)
  4137 
  4086 
  4138 lemmas word_rotr_dt_no_bin' [simp] =
  4087 lemmas word_rotr_dt_no_bin' [simp] =
  4139   word_rotr_dt [where w="numeral w", unfolded to_bl_numeral] for w
  4088   word_rotr_dt [where w="numeral w", unfolded to_bl_numeral] for w
  4140   (* FIXME: negative numerals, 0 and 1 *)
  4089   (* FIXME: negative numerals, 0 and 1 *)
  4141 
  4090 
  4147 
  4096 
  4148 
  4097 
  4149 subsection \<open>Maximum machine word\<close>
  4098 subsection \<open>Maximum machine word\<close>
  4150 
  4099 
  4151 lemma word_int_cases:
  4100 lemma word_int_cases:
  4152   obtains n where "(x ::'a::len0 word) = word_of_int n" and "0 \<le> n" and "n < 2^len_of TYPE('a)"
  4101   fixes x :: "'a::len0 word"
       
  4102   obtains n where "x = word_of_int n" and "0 \<le> n" and "n < 2^len_of TYPE('a)"
  4153   by (cases x rule: word_uint.Abs_cases) (simp add: uints_num)
  4103   by (cases x rule: word_uint.Abs_cases) (simp add: uints_num)
  4154 
  4104 
  4155 lemma word_nat_cases [cases type: word]:
  4105 lemma word_nat_cases [cases type: word]:
  4156   obtains n where "(x ::'a::len word) = of_nat n" and "n < 2^len_of TYPE('a)"
  4106   fixes x :: "'a::len word"
       
  4107   obtains n where "x = of_nat n" and "n < 2^len_of TYPE('a)"
  4157   by (cases x rule: word_unat.Abs_cases) (simp add: unats_def)
  4108   by (cases x rule: word_unat.Abs_cases) (simp add: unats_def)
  4158 
  4109 
  4159 lemma max_word_eq: "(max_word::'a::len word) = 2^len_of TYPE('a) - 1"
  4110 lemma max_word_eq: "(max_word::'a::len word) = 2^len_of TYPE('a) - 1"
  4160   by (simp add: max_word_def word_of_int_hom_syms word_of_int_2p)
  4111   by (simp add: max_word_def word_of_int_hom_syms word_of_int_2p)
  4161 
  4112 
  4164     (simp add: max_word_def word_le_def int_word_uint mod_pos_pos_trivial del: minus_mod_self1)
  4115     (simp add: max_word_def word_le_def int_word_uint mod_pos_pos_trivial del: minus_mod_self1)
  4165 
  4116 
  4166 lemma word_of_int_2p_len: "word_of_int (2 ^ len_of TYPE('a)) = (0::'a::len0 word)"
  4117 lemma word_of_int_2p_len: "word_of_int (2 ^ len_of TYPE('a)) = (0::'a::len0 word)"
  4167   by (subst word_uint.Abs_norm [symmetric]) simp
  4118   by (subst word_uint.Abs_norm [symmetric]) simp
  4168 
  4119 
  4169 lemma word_pow_0:
  4120 lemma word_pow_0: "(2::'a::len word) ^ len_of TYPE('a) = 0"
  4170   "(2::'a::len word) ^ len_of TYPE('a) = 0"
       
  4171 proof -
  4121 proof -
  4172   have "word_of_int (2 ^ len_of TYPE('a)) = (0::'a word)"
  4122   have "word_of_int (2 ^ len_of TYPE('a)) = (0::'a word)"
  4173     by (rule word_of_int_2p_len)
  4123     by (rule word_of_int_2p_len)
  4174   thus ?thesis by (simp add: word_of_int_2p)
  4124   then show ?thesis by (simp add: word_of_int_2p)
  4175 qed
  4125 qed
  4176 
  4126 
  4177 lemma max_word_wrap: "x + 1 = 0 \<Longrightarrow> x = max_word"
  4127 lemma max_word_wrap: "x + 1 = 0 \<Longrightarrow> x = max_word"
  4178   apply (simp add: max_word_eq)
  4128   apply (simp add: max_word_eq)
  4179   apply uint_arith
  4129   apply uint_arith
  4180   apply auto
  4130   apply (auto simp: word_pow_0)
  4181   apply (simp add: word_pow_0)
  4131   done
  4182   done
  4132 
  4183 
  4133 lemma max_word_minus: "max_word = (-1::'a::len word)"
  4184 lemma max_word_minus:
       
  4185   "max_word = (-1::'a::len word)"
       
  4186 proof -
  4134 proof -
  4187   have "-1 + 1 = (0::'a word)" by simp
  4135   have "-1 + 1 = (0::'a word)"
  4188   thus ?thesis by (rule max_word_wrap [symmetric])
  4136     by simp
       
  4137   then show ?thesis
       
  4138     by (rule max_word_wrap [symmetric])
  4189 qed
  4139 qed
  4190 
  4140 
  4191 lemma max_word_bl [simp]:
  4141 lemma max_word_bl [simp]: "to_bl (max_word::'a::len word) = replicate (len_of TYPE('a)) True"
  4192   "to_bl (max_word::'a::len word) = replicate (len_of TYPE('a)) True"
       
  4193   by (subst max_word_minus to_bl_n1)+ simp
  4142   by (subst max_word_minus to_bl_n1)+ simp
  4194 
  4143 
  4195 lemma max_test_bit [simp]:
  4144 lemma max_test_bit [simp]: "(max_word::'a::len word) !! n \<longleftrightarrow> n < len_of TYPE('a)"
  4196   "(max_word::'a::len word) !! n = (n < len_of TYPE('a))"
  4145   by (auto simp: test_bit_bl word_size)
  4197   by (auto simp add: test_bit_bl word_size)
  4146 
  4198 
  4147 lemma word_and_max [simp]: "x AND max_word = x"
  4199 lemma word_and_max [simp]:
       
  4200   "x AND max_word = x"
       
  4201   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
  4148   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
  4202 
  4149 
  4203 lemma word_or_max [simp]:
  4150 lemma word_or_max [simp]: "x OR max_word = max_word"
  4204   "x OR max_word = max_word"
       
  4205   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
  4151   by (rule word_eqI) (simp add: word_ops_nth_size word_size)
  4206 
  4152 
  4207 lemma word_ao_dist2:
  4153 lemma word_ao_dist2: "x AND (y OR z) = x AND y OR x AND z"
  4208   "x AND (y OR z) = x AND y OR x AND (z::'a::len0 word)"
  4154   for x y z :: "'a::len0 word"
  4209   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4155   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4210 
  4156 
  4211 lemma word_oa_dist2:
  4157 lemma word_oa_dist2: "x OR y AND z = (x OR y) AND (x OR z)"
  4212   "x OR y AND z = (x OR y) AND (x OR (z::'a::len0 word))"
  4158   for x y z :: "'a::len0 word"
  4213   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4159   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4214 
  4160 
  4215 lemma word_and_not [simp]:
  4161 lemma word_and_not [simp]: "x AND NOT x = 0"
  4216   "x AND NOT x = (0::'a::len0 word)"
  4162   for x :: "'a::len0 word"
  4217   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4163   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4218 
  4164 
  4219 lemma word_or_not [simp]:
  4165 lemma word_or_not [simp]: "x OR NOT x = max_word"
  4220   "x OR NOT x = max_word"
       
  4221   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4166   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4222 
  4167 
  4223 lemma word_boolean:
  4168 lemma word_boolean: "boolean (op AND) (op OR) bitNOT 0 max_word"
  4224   "boolean (op AND) (op OR) bitNOT 0 max_word"
       
  4225   apply (rule boolean.intro)
  4169   apply (rule boolean.intro)
  4226            apply (rule word_bw_assocs)
  4170            apply (rule word_bw_assocs)
  4227           apply (rule word_bw_assocs)
  4171           apply (rule word_bw_assocs)
  4228          apply (rule word_bw_comms)
  4172          apply (rule word_bw_comms)
  4229         apply (rule word_bw_comms)
  4173         apply (rule word_bw_comms)
  4233     apply (rule word_log_esimps)
  4177     apply (rule word_log_esimps)
  4234    apply (rule word_and_not)
  4178    apply (rule word_and_not)
  4235   apply (rule word_or_not)
  4179   apply (rule word_or_not)
  4236   done
  4180   done
  4237 
  4181 
  4238 interpretation word_bool_alg:
  4182 interpretation word_bool_alg: boolean "op AND" "op OR" bitNOT 0 max_word
  4239   boolean "op AND" "op OR" bitNOT 0 max_word
       
  4240   by (rule word_boolean)
  4183   by (rule word_boolean)
  4241 
  4184 
  4242 lemma word_xor_and_or:
  4185 lemma word_xor_and_or: "x XOR y = x AND NOT y OR NOT x AND y"
  4243   "x XOR y = x AND NOT y OR NOT x AND (y::'a::len0 word)"
  4186   for x y :: "'a::len0 word"
  4244   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4187   by (rule word_eqI) (auto simp add: word_ops_nth_size word_size)
  4245 
  4188 
  4246 interpretation word_bool_alg:
  4189 interpretation word_bool_alg: boolean_xor "op AND" "op OR" bitNOT 0 max_word "op XOR"
  4247   boolean_xor "op AND" "op OR" bitNOT 0 max_word "op XOR"
       
  4248   apply (rule boolean_xor.intro)
  4190   apply (rule boolean_xor.intro)
  4249    apply (rule word_boolean)
  4191    apply (rule word_boolean)
  4250   apply (rule boolean_xor_axioms.intro)
  4192   apply (rule boolean_xor_axioms.intro)
  4251   apply (rule word_xor_and_or)
  4193   apply (rule word_xor_and_or)
  4252   done
  4194   done
  4253 
  4195 
  4254 lemma shiftr_x_0 [iff]:
  4196 lemma shiftr_x_0 [iff]: "x >> 0 = x"
  4255   "(x::'a::len0 word) >> 0 = x"
  4197   for x :: "'a::len0 word"
  4256   by (simp add: shiftr_bl)
  4198   by (simp add: shiftr_bl)
  4257 
  4199 
  4258 lemma shiftl_x_0 [simp]:
  4200 lemma shiftl_x_0 [simp]: "x << 0 = x"
  4259   "(x :: 'a::len word) << 0 = x"
  4201   for x :: "'a::len word"
  4260   by (simp add: shiftl_t2n)
  4202   by (simp add: shiftl_t2n)
  4261 
  4203 
  4262 lemma shiftl_1 [simp]:
  4204 lemma shiftl_1 [simp]: "(1::'a::len word) << n = 2^n"
  4263   "(1::'a::len word) << n = 2^n"
       
  4264   by (simp add: shiftl_t2n)
  4205   by (simp add: shiftl_t2n)
  4265 
  4206 
  4266 lemma uint_lt_0 [simp]:
  4207 lemma uint_lt_0 [simp]: "uint x < 0 = False"
  4267   "uint x < 0 = False"
       
  4268   by (simp add: linorder_not_less)
  4208   by (simp add: linorder_not_less)
  4269 
  4209 
  4270 lemma shiftr1_1 [simp]:
  4210 lemma shiftr1_1 [simp]: "shiftr1 (1::'a::len word) = 0"
  4271   "shiftr1 (1::'a::len word) = 0"
       
  4272   unfolding shiftr1_def by simp
  4211   unfolding shiftr1_def by simp
  4273 
  4212 
  4274 lemma shiftr_1[simp]:
  4213 lemma shiftr_1[simp]: "(1::'a::len word) >> n = (if n = 0 then 1 else 0)"
  4275   "(1::'a::len word) >> n = (if n = 0 then 1 else 0)"
       
  4276   by (induct n) (auto simp: shiftr_def)
  4214   by (induct n) (auto simp: shiftr_def)
  4277 
  4215 
  4278 lemma word_less_1 [simp]:
  4216 lemma word_less_1 [simp]: "x < 1 \<longleftrightarrow> x = 0"
  4279   "((x::'a::len word) < 1) = (x = 0)"
  4217   for x :: "'a::len word"
  4280   by (simp add: word_less_nat_alt unat_0_iff)
  4218   by (simp add: word_less_nat_alt unat_0_iff)
  4281 
  4219 
  4282 lemma to_bl_mask:
  4220 lemma to_bl_mask:
  4283   "to_bl (mask n :: 'a::len word) =
  4221   "to_bl (mask n :: 'a::len word) =
  4284   replicate (len_of TYPE('a) - n) False @
  4222   replicate (len_of TYPE('a) - n) False @
  4285     replicate (min (len_of TYPE('a)) n) True"
  4223     replicate (min (len_of TYPE('a)) n) True"
  4286   by (simp add: mask_bl word_rep_drop min_def)
  4224   by (simp add: mask_bl word_rep_drop min_def)
  4287 
  4225 
  4288 lemma map_replicate_True:
  4226 lemma map_replicate_True:
  4289   "n = length xs \<Longrightarrow>
  4227   "n = length xs \<Longrightarrow>
  4290     map (\<lambda>(x,y). x & y) (zip xs (replicate n True)) = xs"
  4228     map (\<lambda>(x,y). x \<and> y) (zip xs (replicate n True)) = xs"
  4291   by (induct xs arbitrary: n) auto
  4229   by (induct xs arbitrary: n) auto
  4292 
  4230 
  4293 lemma map_replicate_False:
  4231 lemma map_replicate_False:
  4294   "n = length xs \<Longrightarrow> map (\<lambda>(x,y). x & y)
  4232   "n = length xs \<Longrightarrow> map (\<lambda>(x,y). x \<and> y)
  4295     (zip xs (replicate n False)) = replicate n False"
  4233     (zip xs (replicate n False)) = replicate n False"
  4296   by (induct xs arbitrary: n) auto
  4234   by (induct xs arbitrary: n) auto
  4297 
  4235 
  4298 lemma bl_and_mask:
  4236 lemma bl_and_mask:
  4299   fixes w :: "'a::len word"
  4237   fixes w :: "'a::len word"
  4300   fixes n
  4238     and n :: nat
  4301   defines "n' \<equiv> len_of TYPE('a) - n"
  4239   defines "n' \<equiv> len_of TYPE('a) - n"
  4302   shows "to_bl (w AND mask n) =  replicate n' False @ drop n' (to_bl w)"
  4240   shows "to_bl (w AND mask n) = replicate n' False @ drop n' (to_bl w)"
  4303 proof -
  4241 proof -
  4304   note [simp] = map_replicate_True map_replicate_False
  4242   note [simp] = map_replicate_True map_replicate_False
  4305   have "to_bl (w AND mask n) =
  4243   have "to_bl (w AND mask n) = map2 op \<and> (to_bl w) (to_bl (mask n::'a::len word))"
  4306         map2 op & (to_bl w) (to_bl (mask n::'a::len word))"
       
  4307     by (simp add: bl_word_and)
  4244     by (simp add: bl_word_and)
  4308   also
  4245   also have "to_bl w = take n' (to_bl w) @ drop n' (to_bl w)"
  4309   have "to_bl w = take n' (to_bl w) @ drop n' (to_bl w)" by simp
  4246     by simp
  4310   also
  4247   also have "map2 op \<and> \<dots> (to_bl (mask n::'a::len word)) =
  4311   have "map2 op & \<dots> (to_bl (mask n::'a::len word)) =
  4248       replicate n' False @ drop n' (to_bl w)"
  4312         replicate n' False @ drop n' (to_bl w)"
  4249     unfolding to_bl_mask n'_def map2_def by (subst zip_append) auto
  4313     unfolding to_bl_mask n'_def map2_def
  4250   finally show ?thesis .
  4314     by (subst zip_append) auto
       
  4315   finally
       
  4316   show ?thesis .
       
  4317 qed
  4251 qed
  4318 
  4252 
  4319 lemma drop_rev_takefill:
  4253 lemma drop_rev_takefill:
  4320   "length xs \<le> n \<Longrightarrow>
  4254   "length xs \<le> n \<Longrightarrow>
  4321     drop (n - length xs) (rev (takefill False n (rev xs))) = xs"
  4255     drop (n - length xs) (rev (takefill False n (rev xs))) = xs"
  4322   by (simp add: takefill_alt rev_take)
  4256   by (simp add: takefill_alt rev_take)
  4323 
  4257 
  4324 lemma map_nth_0 [simp]:
  4258 lemma map_nth_0 [simp]: "map (op !! (0::'a::len0 word)) xs = replicate (length xs) False"
  4325   "map (op !! (0::'a::len0 word)) xs = replicate (length xs) False"
       
  4326   by (induct xs) auto
  4259   by (induct xs) auto
  4327 
  4260 
  4328 lemma uint_plus_if_size:
  4261 lemma uint_plus_if_size:
  4329   "uint (x + y) =
  4262   "uint (x + y) =
  4330   (if uint x + uint y < 2^size x then
  4263     (if uint x + uint y < 2^size x
  4331       uint x + uint y
  4264      then uint x + uint y
  4332    else
  4265      else uint x + uint y - 2^size x)"
  4333       uint x + uint y - 2^size x)"
  4266   by (simp add: word_arith_wis int_word_uint mod_add_if_z word_size)
  4334   by (simp add: word_arith_wis int_word_uint mod_add_if_z
       
  4335                 word_size)
       
  4336 
  4267 
  4337 lemma unat_plus_if_size:
  4268 lemma unat_plus_if_size:
  4338   "unat (x + (y::'a::len word)) =
  4269   "unat (x + (y::'a::len word)) =
  4339   (if unat x + unat y < 2^size x then
  4270     (if unat x + unat y < 2^size x
  4340       unat x + unat y
  4271      then unat x + unat y
  4341    else
  4272      else unat x + unat y - 2^size x)"
  4342       unat x + unat y - 2^size x)"
       
  4343   apply (subst word_arith_nat_defs)
  4273   apply (subst word_arith_nat_defs)
  4344   apply (subst unat_of_nat)
  4274   apply (subst unat_of_nat)
  4345   apply (simp add:  mod_nat_add word_size)
  4275   apply (simp add:  mod_nat_add word_size)
  4346   done
  4276   done
  4347 
  4277 
  4348 lemma word_neq_0_conv:
  4278 lemma word_neq_0_conv: "w \<noteq> 0 \<longleftrightarrow> 0 < w"
  4349   fixes w :: "'a::len word"
  4279   for w :: "'a::len word"
  4350   shows "(w \<noteq> 0) = (0 < w)"
  4280   by (simp add: word_gt_0)
  4351   unfolding word_gt_0 by simp
  4281 
  4352 
  4282 lemma max_lt: "unat (max a b div c) = unat (max a b) div unat c"
  4353 lemma max_lt:
  4283   for c :: "'a::len word"
  4354   "unat (max a b div c) = unat (max a b) div unat (c:: 'a::len word)"
       
  4355   by (fact unat_div)
  4284   by (fact unat_div)
  4356 
  4285 
  4357 lemma uint_sub_if_size:
  4286 lemma uint_sub_if_size:
  4358   "uint (x - y) =
  4287   "uint (x - y) =
  4359   (if uint y \<le> uint x then
  4288     (if uint y \<le> uint x
  4360       uint x - uint y
  4289      then uint x - uint y
  4361    else
  4290      else uint x - uint y + 2^size x)"
  4362       uint x - uint y + 2^size x)"
  4291   by (simp add: word_arith_wis int_word_uint mod_sub_if_z word_size)
  4363   by (simp add: word_arith_wis int_word_uint mod_sub_if_z
  4292 
  4364                 word_size)
  4293 lemma unat_sub: "b \<le> a \<Longrightarrow> unat (a - b) = unat a - unat b"
  4365 
       
  4366 lemma unat_sub:
       
  4367   "b <= a \<Longrightarrow> unat (a - b) = unat a - unat b"
       
  4368   by (simp add: unat_def uint_sub_if_size word_le_def nat_diff_distrib)
  4294   by (simp add: unat_def uint_sub_if_size word_le_def nat_diff_distrib)
  4369 
  4295 
  4370 lemmas word_less_sub1_numberof [simp] = word_less_sub1 [of "numeral w"] for w
  4296 lemmas word_less_sub1_numberof [simp] = word_less_sub1 [of "numeral w"] for w
  4371 lemmas word_le_sub1_numberof [simp] = word_le_sub1 [of "numeral w"] for w
  4297 lemmas word_le_sub1_numberof [simp] = word_le_sub1 [of "numeral w"] for w
  4372 
  4298 
  4373 lemma word_of_int_minus:
  4299 lemma word_of_int_minus: "word_of_int (2^len_of TYPE('a) - i) = (word_of_int (-i)::'a::len word)"
  4374   "word_of_int (2^len_of TYPE('a) - i) = (word_of_int (-i)::'a::len word)"
       
  4375 proof -
  4300 proof -
  4376   have x: "2^len_of TYPE('a) - i = -i + 2^len_of TYPE('a)" by simp
  4301   have *: "2^len_of TYPE('a) - i = -i + 2^len_of TYPE('a)"
       
  4302     by simp
  4377   show ?thesis
  4303   show ?thesis
  4378     apply (subst x)
  4304     apply (subst *)
  4379     apply (subst word_uint.Abs_norm [symmetric], subst mod_add_self2)
  4305     apply (subst word_uint.Abs_norm [symmetric], subst mod_add_self2)
  4380     apply simp
  4306     apply simp
  4381     done
  4307     done
  4382 qed
  4308 qed
  4383 
  4309 
  4384 lemmas word_of_int_inj =
  4310 lemmas word_of_int_inj =
  4385   word_uint.Abs_inject [unfolded uints_num, simplified]
  4311   word_uint.Abs_inject [unfolded uints_num, simplified]
  4386 
  4312 
  4387 lemma word_le_less_eq:
  4313 lemma word_le_less_eq: "x \<le> y \<longleftrightarrow> x = y \<or> x < y"
  4388   "(x ::'z::len word) \<le> y = (x = y \<or> x < y)"
  4314   for x y :: "'z::len word"
  4389   by (auto simp add: order_class.le_less)
  4315   by (auto simp add: order_class.le_less)
  4390 
  4316 
  4391 lemma mod_plus_cong:
  4317 lemma mod_plus_cong:
  4392   assumes 1: "(b::int) = b'"
  4318   fixes b b' :: int
  4393       and 2: "x mod b' = x' mod b'"
  4319   assumes 1: "b = b'"
  4394       and 3: "y mod b' = y' mod b'"
  4320     and 2: "x mod b' = x' mod b'"
  4395       and 4: "x' + y' = z'"
  4321     and 3: "y mod b' = y' mod b'"
       
  4322     and 4: "x' + y' = z'"
  4396   shows "(x + y) mod b = z' mod b'"
  4323   shows "(x + y) mod b = z' mod b'"
  4397 proof -
  4324 proof -
  4398   from 1 2[symmetric] 3[symmetric] have "(x + y) mod b = (x' mod b' + y' mod b') mod b'"
  4325   from 1 2[symmetric] 3[symmetric] have "(x + y) mod b = (x' mod b' + y' mod b') mod b'"
  4399     by (simp add: mod_add_eq)
  4326     by (simp add: mod_add_eq)
  4400   also have "\<dots> = (x' + y') mod b'"
  4327   also have "\<dots> = (x' + y') mod b'"
  4401     by (simp add: mod_add_eq)
  4328     by (simp add: mod_add_eq)
  4402   finally show ?thesis by (simp add: 4)
  4329   finally show ?thesis
       
  4330     by (simp add: 4)
  4403 qed
  4331 qed
  4404 
  4332 
  4405 lemma mod_minus_cong:
  4333 lemma mod_minus_cong:
  4406   assumes 1: "(b::int) = b'"
  4334   fixes b b' :: int
  4407       and 2: "x mod b' = x' mod b'"
  4335   assumes "b = b'"
  4408       and 3: "y mod b' = y' mod b'"
  4336     and "x mod b' = x' mod b'"
  4409       and 4: "x' - y' = z'"
  4337     and "y mod b' = y' mod b'"
       
  4338     and "x' - y' = z'"
  4410   shows "(x - y) mod b = z' mod b'"
  4339   shows "(x - y) mod b = z' mod b'"
  4411   using 1 2 3 4 [symmetric]
  4340   using assms [symmetric] by (auto intro: mod_diff_cong)
  4412   by (auto intro: mod_diff_cong)
  4341 
  4413 
  4342 lemma word_induct_less: "\<lbrakk>P 0; \<And>n. \<lbrakk>n < m; P n\<rbrakk> \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P m"
  4414 lemma word_induct_less:
  4343   for P :: "'a::len word \<Rightarrow> bool"
  4415   "\<lbrakk>P (0::'a::len word); \<And>n. \<lbrakk>n < m; P n\<rbrakk> \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P m"
       
  4416   apply (cases m)
  4344   apply (cases m)
  4417   apply atomize
  4345   apply atomize
  4418   apply (erule rev_mp)+
  4346   apply (erule rev_mp)+
  4419   apply (rule_tac x=m in spec)
  4347   apply (rule_tac x=m in spec)
  4420   apply (induct_tac n)
  4348   apply (induct_tac n)
  4432    apply (simp add: unat_arith_simps)
  4360    apply (simp add: unat_arith_simps)
  4433    apply (clarsimp simp: unat_of_nat)
  4361    apply (clarsimp simp: unat_of_nat)
  4434   apply simp
  4362   apply simp
  4435   done
  4363   done
  4436 
  4364 
  4437 lemma word_induct:
  4365 lemma word_induct: "\<lbrakk>P 0; \<And>n. P n \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P m"
  4438   "\<lbrakk>P (0::'a::len word); \<And>n. P n \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P m"
  4366   for P :: "'a::len word \<Rightarrow> bool"
  4439   by (erule word_induct_less, simp)
  4367   by (erule word_induct_less) simp
  4440 
  4368 
  4441 lemma word_induct2 [induct type]:
  4369 lemma word_induct2 [induct type]: "\<lbrakk>P 0; \<And>n. \<lbrakk>1 + n \<noteq> 0; P n\<rbrakk> \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P n"
  4442   "\<lbrakk>P 0; \<And>n. \<lbrakk>1 + n \<noteq> 0; P n\<rbrakk> \<Longrightarrow> P (1 + n)\<rbrakk> \<Longrightarrow> P (n::'b::len word)"
  4370   for P :: "'b::len word \<Rightarrow> bool"
  4443   apply (rule word_induct, simp)
  4371   apply (rule word_induct)
  4444   apply (case_tac "1+n = 0", auto)
  4372    apply simp
       
  4373   apply (case_tac "1 + n = 0")
       
  4374    apply auto
  4445   done
  4375   done
  4446 
  4376 
  4447 
  4377 
  4448 subsection \<open>Recursion combinator for words\<close>
  4378 subsection \<open>Recursion combinator for words\<close>
  4449 
  4379 
  4450 definition word_rec :: "'a \<Rightarrow> ('b::len word \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'b word \<Rightarrow> 'a"
  4380 definition word_rec :: "'a \<Rightarrow> ('b::len word \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'b word \<Rightarrow> 'a"
  4451 where
  4381   where "word_rec forZero forSuc n = rec_nat forZero (forSuc \<circ> of_nat) (unat n)"
  4452   "word_rec forZero forSuc n = rec_nat forZero (forSuc \<circ> of_nat) (unat n)"
       
  4453 
  4382 
  4454 lemma word_rec_0: "word_rec z s 0 = z"
  4383 lemma word_rec_0: "word_rec z s 0 = z"
  4455   by (simp add: word_rec_def)
  4384   by (simp add: word_rec_def)
  4456 
  4385 
  4457 lemma word_rec_Suc:
  4386 lemma word_rec_Suc:
  4469   apply (subst word_rec_Suc)
  4398   apply (subst word_rec_Suc)
  4470    apply simp
  4399    apply simp
  4471   apply simp
  4400   apply simp
  4472   done
  4401   done
  4473 
  4402 
  4474 lemma word_rec_in:
  4403 lemma word_rec_in: "f (word_rec z (\<lambda>_. f) n) = word_rec (f z) (\<lambda>_. f) n"
  4475   "f (word_rec z (\<lambda>_. f) n) = word_rec (f z) (\<lambda>_. f) n"
       
  4476   by (induct n) (simp_all add: word_rec_0 word_rec_Suc)
  4404   by (induct n) (simp_all add: word_rec_0 word_rec_Suc)
  4477 
  4405 
  4478 lemma word_rec_in2:
  4406 lemma word_rec_in2: "f n (word_rec z f n) = word_rec (f 0 z) (f \<circ> op + 1) n"
  4479   "f n (word_rec z f n) = word_rec (f 0 z) (f \<circ> op + 1) n"
       
  4480   by (induct n) (simp_all add: word_rec_0 word_rec_Suc)
  4407   by (induct n) (simp_all add: word_rec_0 word_rec_Suc)
  4481 
  4408 
  4482 lemma word_rec_twice:
  4409 lemma word_rec_twice:
  4483   "m \<le> n \<Longrightarrow> word_rec z f n = word_rec (word_rec z f (n - m)) (f \<circ> op + (n - m)) m"
  4410   "m \<le> n \<Longrightarrow> word_rec z f n = word_rec (word_rec z f (n - m)) (f \<circ> op + (n - m)) m"
  4484 apply (erule rev_mp)
  4411   apply (erule rev_mp)
  4485 apply (rule_tac x=z in spec)
  4412   apply (rule_tac x=z in spec)
  4486 apply (rule_tac x=f in spec)
  4413   apply (rule_tac x=f in spec)
  4487 apply (induct n)
  4414   apply (induct n)
  4488  apply (simp add: word_rec_0)
  4415    apply (simp add: word_rec_0)
  4489 apply clarsimp
  4416   apply clarsimp
  4490 apply (rule_tac t="1 + n - m" and s="1 + (n - m)" in subst)
  4417   apply (rule_tac t="1 + n - m" and s="1 + (n - m)" in subst)
  4491  apply simp
  4418    apply simp
  4492 apply (case_tac "1 + (n - m) = 0")
  4419   apply (case_tac "1 + (n - m) = 0")
  4493  apply (simp add: word_rec_0)
  4420    apply (simp add: word_rec_0)
  4494  apply (rule_tac f = "word_rec a b" for a b in arg_cong)
  4421    apply (rule_tac f = "word_rec a b" for a b in arg_cong)
  4495  apply (rule_tac t="m" and s="m + (1 + (n - m))" in subst)
  4422    apply (rule_tac t="m" and s="m + (1 + (n - m))" in subst)
       
  4423     apply simp
       
  4424    apply (simp (no_asm_use))
       
  4425   apply (simp add: word_rec_Suc word_rec_in2)
       
  4426   apply (erule impE)
       
  4427    apply uint_arith
       
  4428   apply (drule_tac x="x \<circ> op + 1" in spec)
       
  4429   apply (drule_tac x="x 0 xa" in spec)
  4496   apply simp
  4430   apply simp
  4497  apply (simp (no_asm_use))
  4431   apply (rule_tac t="\<lambda>a. x (1 + (n - m + a))" and s="\<lambda>a. x (1 + (n - m) + a)" in subst)
  4498 apply (simp add: word_rec_Suc word_rec_in2)
  4432    apply (clarsimp simp add: fun_eq_iff)
  4499 apply (erule impE)
  4433    apply (rule_tac t="(1 + (n - m + xb))" and s="1 + (n - m) + xb" in subst)
  4500  apply uint_arith
  4434     apply simp
  4501 apply (drule_tac x="x \<circ> op + 1" in spec)
  4435    apply (rule refl)
  4502 apply (drule_tac x="x 0 xa" in spec)
  4436   apply (rule refl)
  4503 apply simp
  4437   done
  4504 apply (rule_tac t="\<lambda>a. x (1 + (n - m + a))" and s="\<lambda>a. x (1 + (n - m) + a)"
       
  4505        in subst)
       
  4506  apply (clarsimp simp add: fun_eq_iff)
       
  4507  apply (rule_tac t="(1 + (n - m + xb))" and s="1 + (n - m) + xb" in subst)
       
  4508   apply simp
       
  4509  apply (rule refl)
       
  4510 apply (rule refl)
       
  4511 done
       
  4512 
  4438 
  4513 lemma word_rec_id: "word_rec z (\<lambda>_. id) n = z"
  4439 lemma word_rec_id: "word_rec z (\<lambda>_. id) n = z"
  4514   by (induct n) (auto simp add: word_rec_0 word_rec_Suc)
  4440   by (induct n) (auto simp add: word_rec_0 word_rec_Suc)
  4515 
  4441 
  4516 lemma word_rec_id_eq: "\<forall>m < n. f m = id \<Longrightarrow> word_rec z f n = z"
  4442 lemma word_rec_id_eq: "\<forall>m < n. f m = id \<Longrightarrow> word_rec z f n = z"
  4517 apply (erule rev_mp)
  4443   apply (erule rev_mp)
  4518 apply (induct n)
  4444   apply (induct n)
  4519  apply (auto simp add: word_rec_0 word_rec_Suc)
  4445    apply (auto simp add: word_rec_0 word_rec_Suc)
  4520  apply (drule spec, erule mp)
  4446    apply (drule spec, erule mp)
  4521  apply uint_arith
  4447    apply uint_arith
  4522 apply (drule_tac x=n in spec, erule impE)
  4448   apply (drule_tac x=n in spec, erule impE)
  4523  apply uint_arith
  4449    apply uint_arith
  4524 apply simp
  4450   apply simp
  4525 done
  4451   done
  4526 
  4452 
  4527 lemma word_rec_max:
  4453 lemma word_rec_max:
  4528   "\<forall>m\<ge>n. m \<noteq> - 1 \<longrightarrow> f m = id \<Longrightarrow> word_rec z f (- 1) = word_rec z f n"
  4454   "\<forall>m\<ge>n. m \<noteq> - 1 \<longrightarrow> f m = id \<Longrightarrow> word_rec z f (- 1) = word_rec z f n"
  4529 apply (subst word_rec_twice[where n="-1" and m="-1 - n"])
  4455   apply (subst word_rec_twice[where n="-1" and m="-1 - n"])
  4530  apply simp
  4456    apply simp
  4531 apply simp
  4457   apply simp
  4532 apply (rule word_rec_id_eq)
  4458   apply (rule word_rec_id_eq)
  4533 apply clarsimp
  4459   apply clarsimp
  4534 apply (drule spec, rule mp, erule mp)
  4460   apply (drule spec, rule mp, erule mp)
  4535  apply (rule word_plus_mono_right2[OF _ order_less_imp_le])
  4461    apply (rule word_plus_mono_right2[OF _ order_less_imp_le])
  4536   prefer 2
  4462     prefer 2
  4537   apply assumption
  4463     apply assumption
  4538  apply simp
  4464    apply simp
  4539 apply (erule contrapos_pn)
  4465   apply (erule contrapos_pn)
  4540 apply simp
  4466   apply simp
  4541 apply (drule arg_cong[where f="\<lambda>x. x - n"])
  4467   apply (drule arg_cong[where f="\<lambda>x. x - n"])
  4542 apply simp
  4468   apply simp
  4543 done
  4469   done
  4544 
  4470 
  4545 lemma unatSuc:
  4471 lemma unatSuc: "1 + n \<noteq> (0::'a::len word) \<Longrightarrow> unat (1 + n) = Suc (unat n)"
  4546   "1 + n \<noteq> (0::'a::len word) \<Longrightarrow> unat (1 + n) = Suc (unat n)"
       
  4547   by unat_arith
  4472   by unat_arith
  4548 
  4473 
  4549 declare bin_to_bl_def [simp]
  4474 declare bin_to_bl_def [simp]
  4550 
  4475 
  4551 ML_file "Tools/word_lib.ML"
  4476 ML_file "Tools/word_lib.ML"