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 |
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] |
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] |
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) |
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" |