16 |
16 |
17 text \<open>See \<^file>\<open>Word_Examples.thy\<close> for examples.\<close> |
17 text \<open>See \<^file>\<open>Word_Examples.thy\<close> for examples.\<close> |
18 |
18 |
19 subsection \<open>Type definition\<close> |
19 subsection \<open>Type definition\<close> |
20 |
20 |
21 typedef (overloaded) 'a word = "{(0::int) ..< 2 ^ len_of TYPE('a::len0)}" |
21 typedef (overloaded) 'a word = "{(0::int) ..< 2 ^ LENGTH('a::len0)}" |
22 morphisms uint Abs_word by auto |
22 morphisms uint Abs_word by auto |
23 |
23 |
24 lemma uint_nonnegative: "0 \<le> uint w" |
24 lemma uint_nonnegative: "0 \<le> uint w" |
25 using word.uint [of w] by simp |
25 using word.uint [of w] by simp |
26 |
26 |
27 lemma uint_bounded: "uint w < 2 ^ len_of TYPE('a)" |
27 lemma uint_bounded: "uint w < 2 ^ LENGTH('a)" |
28 for w :: "'a::len0 word" |
28 for w :: "'a::len0 word" |
29 using word.uint [of w] by simp |
29 using word.uint [of w] by simp |
30 |
30 |
31 lemma uint_idem: "uint w mod 2 ^ len_of TYPE('a) = uint w" |
31 lemma uint_idem: "uint w mod 2 ^ LENGTH('a) = uint w" |
32 for w :: "'a::len0 word" |
32 for w :: "'a::len0 word" |
33 using uint_nonnegative uint_bounded by (rule mod_pos_pos_trivial) |
33 using uint_nonnegative uint_bounded by (rule mod_pos_pos_trivial) |
34 |
34 |
35 lemma word_uint_eq_iff: "a = b \<longleftrightarrow> uint a = uint b" |
35 lemma word_uint_eq_iff: "a = b \<longleftrightarrow> uint a = uint b" |
36 by (simp add: uint_inject) |
36 by (simp add: uint_inject) |
39 by (simp add: word_uint_eq_iff) |
39 by (simp add: word_uint_eq_iff) |
40 |
40 |
41 definition word_of_int :: "int \<Rightarrow> 'a::len0 word" |
41 definition word_of_int :: "int \<Rightarrow> 'a::len0 word" |
42 \<comment> \<open>representation of words using unsigned or signed bins, |
42 \<comment> \<open>representation of words using unsigned or signed bins, |
43 only difference in these is the type class\<close> |
43 only difference in these is the type class\<close> |
44 where "word_of_int k = Abs_word (k mod 2 ^ len_of TYPE('a))" |
44 where "word_of_int k = Abs_word (k mod 2 ^ LENGTH('a))" |
45 |
45 |
46 lemma uint_word_of_int: "uint (word_of_int k :: 'a::len0 word) = k mod 2 ^ len_of TYPE('a)" |
46 lemma uint_word_of_int: "uint (word_of_int k :: 'a::len0 word) = k mod 2 ^ LENGTH('a)" |
47 by (auto simp add: word_of_int_def intro: Abs_word_inverse) |
47 by (auto simp add: word_of_int_def intro: Abs_word_inverse) |
48 |
48 |
49 lemma word_of_int_uint: "word_of_int (uint w) = w" |
49 lemma word_of_int_uint: "word_of_int (uint w) = w" |
50 by (simp add: word_of_int_def uint_idem uint_inverse) |
50 by (simp add: word_of_int_def uint_idem uint_inverse) |
51 |
51 |
148 |
148 |
149 definition cr_word :: "int \<Rightarrow> 'a::len0 word \<Rightarrow> bool" |
149 definition cr_word :: "int \<Rightarrow> 'a::len0 word \<Rightarrow> bool" |
150 where "cr_word = (\<lambda>x y. word_of_int x = y)" |
150 where "cr_word = (\<lambda>x y. word_of_int x = y)" |
151 |
151 |
152 lemma Quotient_word: |
152 lemma Quotient_word: |
153 "Quotient (\<lambda>x y. bintrunc (len_of TYPE('a)) x = bintrunc (len_of TYPE('a)) y) |
153 "Quotient (\<lambda>x y. bintrunc (LENGTH('a)) x = bintrunc (LENGTH('a)) y) |
154 word_of_int uint (cr_word :: _ \<Rightarrow> 'a::len0 word \<Rightarrow> bool)" |
154 word_of_int uint (cr_word :: _ \<Rightarrow> 'a::len0 word \<Rightarrow> bool)" |
155 unfolding Quotient_alt_def cr_word_def |
155 unfolding Quotient_alt_def cr_word_def |
156 by (simp add: no_bintr_alt1 word_of_int_uint) (simp add: word_of_int_def Abs_word_inject) |
156 by (simp add: no_bintr_alt1 word_of_int_uint) (simp add: word_of_int_def Abs_word_inject) |
157 |
157 |
158 lemma reflp_word: |
158 lemma reflp_word: |
159 "reflp (\<lambda>x y. bintrunc (len_of TYPE('a::len0)) x = bintrunc (len_of TYPE('a)) y)" |
159 "reflp (\<lambda>x y. bintrunc (LENGTH('a::len0)) x = bintrunc (LENGTH('a)) y)" |
160 by (simp add: reflp_def) |
160 by (simp add: reflp_def) |
161 |
161 |
162 setup_lifting Quotient_word reflp_word |
162 setup_lifting Quotient_word reflp_word |
163 |
163 |
164 text \<open>TODO: The next lemma could be generated automatically.\<close> |
164 text \<open>TODO: The next lemma could be generated automatically.\<close> |
165 |
165 |
166 lemma uint_transfer [transfer_rule]: |
166 lemma uint_transfer [transfer_rule]: |
167 "(rel_fun pcr_word (=)) (bintrunc (len_of TYPE('a))) (uint :: 'a::len0 word \<Rightarrow> int)" |
167 "(rel_fun pcr_word (=)) (bintrunc (LENGTH('a))) (uint :: 'a::len0 word \<Rightarrow> int)" |
168 unfolding rel_fun_def word.pcr_cr_eq cr_word_def |
168 unfolding rel_fun_def word.pcr_cr_eq cr_word_def |
169 by (simp add: no_bintr_alt1 uint_word_of_int) |
169 by (simp add: no_bintr_alt1 uint_word_of_int) |
170 |
170 |
171 |
171 |
172 subsection \<open>Basic code generation setup\<close> |
172 subsection \<open>Basic code generation setup\<close> |
214 lemmas uint_0 = uint_nonnegative (* FIXME duplicate *) |
214 lemmas uint_0 = uint_nonnegative (* FIXME duplicate *) |
215 lemmas uint_lt = uint_bounded (* FIXME duplicate *) |
215 lemmas uint_lt = uint_bounded (* FIXME duplicate *) |
216 lemmas uint_mod_same = uint_idem (* FIXME duplicate *) |
216 lemmas uint_mod_same = uint_idem (* FIXME duplicate *) |
217 |
217 |
218 lemma td_ext_uint: |
218 lemma td_ext_uint: |
219 "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (len_of TYPE('a::len0))) |
219 "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (LENGTH('a::len0))) |
220 (\<lambda>w::int. w mod 2 ^ len_of TYPE('a))" |
220 (\<lambda>w::int. w mod 2 ^ LENGTH('a))" |
221 apply (unfold td_ext_def') |
221 apply (unfold td_ext_def') |
222 apply (simp add: uints_num word_of_int_def bintrunc_mod2p) |
222 apply (simp add: uints_num word_of_int_def bintrunc_mod2p) |
223 apply (simp add: uint_mod_same uint_0 uint_lt |
223 apply (simp add: uint_mod_same uint_0 uint_lt |
224 word.uint_inverse word.Abs_word_inverse int_mod_lem) |
224 word.uint_inverse word.Abs_word_inverse int_mod_lem) |
225 done |
225 done |
226 |
226 |
227 interpretation word_uint: |
227 interpretation word_uint: |
228 td_ext |
228 td_ext |
229 "uint::'a::len0 word \<Rightarrow> int" |
229 "uint::'a::len0 word \<Rightarrow> int" |
230 word_of_int |
230 word_of_int |
231 "uints (len_of TYPE('a::len0))" |
231 "uints (LENGTH('a::len0))" |
232 "\<lambda>w. w mod 2 ^ len_of TYPE('a::len0)" |
232 "\<lambda>w. w mod 2 ^ LENGTH('a::len0)" |
233 by (fact td_ext_uint) |
233 by (fact td_ext_uint) |
234 |
234 |
235 lemmas td_uint = word_uint.td_thm |
235 lemmas td_uint = word_uint.td_thm |
236 lemmas int_word_uint = word_uint.eq_norm |
236 lemmas int_word_uint = word_uint.eq_norm |
237 |
237 |
238 lemma td_ext_ubin: |
238 lemma td_ext_ubin: |
239 "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (len_of TYPE('a::len0))) |
239 "td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (LENGTH('a::len0))) |
240 (bintrunc (len_of TYPE('a)))" |
240 (bintrunc (LENGTH('a)))" |
241 by (unfold no_bintr_alt1) (fact td_ext_uint) |
241 by (unfold no_bintr_alt1) (fact td_ext_uint) |
242 |
242 |
243 interpretation word_ubin: |
243 interpretation word_ubin: |
244 td_ext |
244 td_ext |
245 "uint::'a::len0 word \<Rightarrow> int" |
245 "uint::'a::len0 word \<Rightarrow> int" |
246 word_of_int |
246 word_of_int |
247 "uints (len_of TYPE('a::len0))" |
247 "uints (LENGTH('a::len0))" |
248 "bintrunc (len_of TYPE('a::len0))" |
248 "bintrunc (LENGTH('a::len0))" |
249 by (fact td_ext_ubin) |
249 by (fact td_ext_ubin) |
250 |
250 |
251 |
251 |
252 subsection \<open>Arithmetic operations\<close> |
252 subsection \<open>Arithmetic operations\<close> |
253 |
253 |
461 |
461 |
462 |
462 |
463 subsection \<open>Split and cat operations\<close> |
463 subsection \<open>Split and cat operations\<close> |
464 |
464 |
465 definition word_cat :: "'a::len0 word \<Rightarrow> 'b::len0 word \<Rightarrow> 'c::len0 word" |
465 definition word_cat :: "'a::len0 word \<Rightarrow> 'b::len0 word \<Rightarrow> 'c::len0 word" |
466 where "word_cat a b = word_of_int (bin_cat (uint a) (len_of TYPE('b)) (uint b))" |
466 where "word_cat a b = word_of_int (bin_cat (uint a) (LENGTH('b)) (uint b))" |
467 |
467 |
468 definition word_split :: "'a::len0 word \<Rightarrow> 'b::len0 word \<times> 'c::len0 word" |
468 definition word_split :: "'a::len0 word \<Rightarrow> 'b::len0 word \<times> 'c::len0 word" |
469 where "word_split a = |
469 where "word_split a = |
470 (case bin_split (len_of TYPE('c)) (uint a) of |
470 (case bin_split (LENGTH('c)) (uint a) of |
471 (u, v) \<Rightarrow> (word_of_int u, word_of_int v))" |
471 (u, v) \<Rightarrow> (word_of_int u, word_of_int v))" |
472 |
472 |
473 definition word_rcat :: "'a::len0 word list \<Rightarrow> 'b::len0 word" |
473 definition word_rcat :: "'a::len0 word list \<Rightarrow> 'b::len0 word" |
474 where "word_rcat ws = word_of_int (bin_rcat (len_of TYPE('a)) (map uint ws))" |
474 where "word_rcat ws = word_of_int (bin_rcat (LENGTH('a)) (map uint ws))" |
475 |
475 |
476 definition word_rsplit :: "'a::len0 word \<Rightarrow> 'b::len word list" |
476 definition word_rsplit :: "'a::len0 word \<Rightarrow> 'b::len word list" |
477 where "word_rsplit w = map word_of_int (bin_rsplit (len_of TYPE('b)) (len_of TYPE('a), uint w))" |
477 where "word_rsplit w = map word_of_int (bin_rsplit (LENGTH('b)) (LENGTH('a), uint w))" |
478 |
478 |
479 definition max_word :: "'a::len word" |
479 definition max_word :: "'a::len word" |
480 \<comment> \<open>Largest representable machine integer.\<close> |
480 \<comment> \<open>Largest representable machine integer.\<close> |
481 where "max_word = word_of_int (2 ^ len_of TYPE('a) - 1)" |
481 where "max_word = word_of_int (2 ^ LENGTH('a) - 1)" |
482 |
482 |
483 lemmas of_nth_def = word_set_bits_def (* FIXME duplicate *) |
483 lemmas of_nth_def = word_set_bits_def (* FIXME duplicate *) |
484 |
484 |
485 |
485 |
486 subsection \<open>Theorems about typedefs\<close> |
486 subsection \<open>Theorems about typedefs\<close> |
487 |
487 |
488 lemma sint_sbintrunc': "sint (word_of_int bin :: 'a word) = sbintrunc (len_of TYPE('a::len) - 1) bin" |
488 lemma sint_sbintrunc': "sint (word_of_int bin :: 'a word) = sbintrunc (LENGTH('a::len) - 1) bin" |
489 by (auto simp: sint_uint word_ubin.eq_norm sbintrunc_bintrunc_lt) |
489 by (auto simp: sint_uint word_ubin.eq_norm sbintrunc_bintrunc_lt) |
490 |
490 |
491 lemma uint_sint: "uint w = bintrunc (len_of TYPE('a)) (sint w)" |
491 lemma uint_sint: "uint w = bintrunc (LENGTH('a)) (sint w)" |
492 for w :: "'a::len word" |
492 for w :: "'a::len word" |
493 by (auto simp: sint_uint bintrunc_sbintrunc_le) |
493 by (auto simp: sint_uint bintrunc_sbintrunc_le) |
494 |
494 |
495 lemma bintr_uint: "len_of TYPE('a) \<le> n \<Longrightarrow> bintrunc n (uint w) = uint w" |
495 lemma bintr_uint: "LENGTH('a) \<le> n \<Longrightarrow> bintrunc n (uint w) = uint w" |
496 for w :: "'a::len0 word" |
496 for w :: "'a::len0 word" |
497 apply (subst word_ubin.norm_Rep [symmetric]) |
497 apply (subst word_ubin.norm_Rep [symmetric]) |
498 apply (simp only: bintrunc_bintrunc_min word_size) |
498 apply (simp only: bintrunc_bintrunc_min word_size) |
499 apply (simp add: min.absorb2) |
499 apply (simp add: min.absorb2) |
500 done |
500 done |
501 |
501 |
502 lemma wi_bintr: |
502 lemma wi_bintr: |
503 "len_of TYPE('a::len0) \<le> n \<Longrightarrow> |
503 "LENGTH('a::len0) \<le> n \<Longrightarrow> |
504 word_of_int (bintrunc n w) = (word_of_int w :: 'a word)" |
504 word_of_int (bintrunc n w) = (word_of_int w :: 'a word)" |
505 by (auto simp: word_ubin.norm_eq_iff [symmetric] min.absorb1) |
505 by (auto simp: word_ubin.norm_eq_iff [symmetric] min.absorb1) |
506 |
506 |
507 lemma td_ext_sbin: |
507 lemma td_ext_sbin: |
508 "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (len_of TYPE('a::len))) |
508 "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (LENGTH('a::len))) |
509 (sbintrunc (len_of TYPE('a) - 1))" |
509 (sbintrunc (LENGTH('a) - 1))" |
510 apply (unfold td_ext_def' sint_uint) |
510 apply (unfold td_ext_def' sint_uint) |
511 apply (simp add : word_ubin.eq_norm) |
511 apply (simp add : word_ubin.eq_norm) |
512 apply (cases "len_of TYPE('a)") |
512 apply (cases "LENGTH('a)") |
513 apply (auto simp add : sints_def) |
513 apply (auto simp add : sints_def) |
514 apply (rule sym [THEN trans]) |
514 apply (rule sym [THEN trans]) |
515 apply (rule word_ubin.Abs_norm) |
515 apply (rule word_ubin.Abs_norm) |
516 apply (simp only: bintrunc_sbintrunc) |
516 apply (simp only: bintrunc_sbintrunc) |
517 apply (drule sym) |
517 apply (drule sym) |
518 apply simp |
518 apply simp |
519 done |
519 done |
520 |
520 |
521 lemma td_ext_sint: |
521 lemma td_ext_sint: |
522 "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (len_of TYPE('a::len))) |
522 "td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (LENGTH('a::len))) |
523 (\<lambda>w. (w + 2 ^ (len_of TYPE('a) - 1)) mod 2 ^ len_of TYPE('a) - |
523 (\<lambda>w. (w + 2 ^ (LENGTH('a) - 1)) mod 2 ^ LENGTH('a) - |
524 2 ^ (len_of TYPE('a) - 1))" |
524 2 ^ (LENGTH('a) - 1))" |
525 using td_ext_sbin [where ?'a = 'a] by (simp add: no_sbintr_alt2) |
525 using td_ext_sbin [where ?'a = 'a] by (simp add: no_sbintr_alt2) |
526 |
526 |
527 text \<open> |
527 text \<open> |
528 We do \<open>sint\<close> before \<open>sbin\<close>, before \<open>sint\<close> is the user version |
528 We do \<open>sint\<close> before \<open>sbin\<close>, before \<open>sint\<close> is the user version |
529 and interpretations do not produce thm duplicates. I.e. |
529 and interpretations do not produce thm duplicates. I.e. |
532 \<close> |
532 \<close> |
533 interpretation word_sint: |
533 interpretation word_sint: |
534 td_ext |
534 td_ext |
535 "sint ::'a::len word \<Rightarrow> int" |
535 "sint ::'a::len word \<Rightarrow> int" |
536 word_of_int |
536 word_of_int |
537 "sints (len_of TYPE('a::len))" |
537 "sints (LENGTH('a::len))" |
538 "\<lambda>w. (w + 2^(len_of TYPE('a::len) - 1)) mod 2^len_of TYPE('a::len) - |
538 "\<lambda>w. (w + 2^(LENGTH('a::len) - 1)) mod 2^LENGTH('a::len) - |
539 2 ^ (len_of TYPE('a::len) - 1)" |
539 2 ^ (LENGTH('a::len) - 1)" |
540 by (rule td_ext_sint) |
540 by (rule td_ext_sint) |
541 |
541 |
542 interpretation word_sbin: |
542 interpretation word_sbin: |
543 td_ext |
543 td_ext |
544 "sint ::'a::len word \<Rightarrow> int" |
544 "sint ::'a::len word \<Rightarrow> int" |
545 word_of_int |
545 word_of_int |
546 "sints (len_of TYPE('a::len))" |
546 "sints (LENGTH('a::len))" |
547 "sbintrunc (len_of TYPE('a::len) - 1)" |
547 "sbintrunc (LENGTH('a::len) - 1)" |
548 by (rule td_ext_sbin) |
548 by (rule td_ext_sbin) |
549 |
549 |
550 lemmas int_word_sint = td_ext_sint [THEN td_ext.eq_norm] |
550 lemmas int_word_sint = td_ext_sint [THEN td_ext.eq_norm] |
551 |
551 |
552 lemmas td_sint = word_sint.td |
552 lemmas td_sint = word_sint.td |
553 |
553 |
554 lemma to_bl_def': "(to_bl :: 'a::len0 word \<Rightarrow> bool list) = bin_to_bl (len_of TYPE('a)) \<circ> uint" |
554 lemma to_bl_def': "(to_bl :: 'a::len0 word \<Rightarrow> bool list) = bin_to_bl (LENGTH('a)) \<circ> uint" |
555 by (auto simp: to_bl_def) |
555 by (auto simp: to_bl_def) |
556 |
556 |
557 lemmas word_reverse_no_def [simp] = |
557 lemmas word_reverse_no_def [simp] = |
558 word_reverse_def [of "numeral w"] for w |
558 word_reverse_def [of "numeral w"] for w |
559 |
559 |
576 apply (simp_all add: rel_fun_def word.pcr_cr_eq cr_word_def) |
576 apply (simp_all add: rel_fun_def word.pcr_cr_eq cr_word_def) |
577 using word_numeral_alt [symmetric] word_neg_numeral_alt [symmetric] by auto |
577 using word_numeral_alt [symmetric] word_neg_numeral_alt [symmetric] by auto |
578 |
578 |
579 lemma uint_bintrunc [simp]: |
579 lemma uint_bintrunc [simp]: |
580 "uint (numeral bin :: 'a word) = |
580 "uint (numeral bin :: 'a word) = |
581 bintrunc (len_of TYPE('a::len0)) (numeral bin)" |
581 bintrunc (LENGTH('a::len0)) (numeral bin)" |
582 unfolding word_numeral_alt by (rule word_ubin.eq_norm) |
582 unfolding word_numeral_alt by (rule word_ubin.eq_norm) |
583 |
583 |
584 lemma uint_bintrunc_neg [simp]: |
584 lemma uint_bintrunc_neg [simp]: |
585 "uint (- numeral bin :: 'a word) = bintrunc (len_of TYPE('a::len0)) (- numeral bin)" |
585 "uint (- numeral bin :: 'a word) = bintrunc (LENGTH('a::len0)) (- numeral bin)" |
586 by (simp only: word_neg_numeral_alt word_ubin.eq_norm) |
586 by (simp only: word_neg_numeral_alt word_ubin.eq_norm) |
587 |
587 |
588 lemma sint_sbintrunc [simp]: |
588 lemma sint_sbintrunc [simp]: |
589 "sint (numeral bin :: 'a word) = sbintrunc (len_of TYPE('a::len) - 1) (numeral bin)" |
589 "sint (numeral bin :: 'a word) = sbintrunc (LENGTH('a::len) - 1) (numeral bin)" |
590 by (simp only: word_numeral_alt word_sbin.eq_norm) |
590 by (simp only: word_numeral_alt word_sbin.eq_norm) |
591 |
591 |
592 lemma sint_sbintrunc_neg [simp]: |
592 lemma sint_sbintrunc_neg [simp]: |
593 "sint (- numeral bin :: 'a word) = sbintrunc (len_of TYPE('a::len) - 1) (- numeral bin)" |
593 "sint (- numeral bin :: 'a word) = sbintrunc (LENGTH('a::len) - 1) (- numeral bin)" |
594 by (simp only: word_neg_numeral_alt word_sbin.eq_norm) |
594 by (simp only: word_neg_numeral_alt word_sbin.eq_norm) |
595 |
595 |
596 lemma unat_bintrunc [simp]: |
596 lemma unat_bintrunc [simp]: |
597 "unat (numeral bin :: 'a::len0 word) = nat (bintrunc (len_of TYPE('a)) (numeral bin))" |
597 "unat (numeral bin :: 'a::len0 word) = nat (bintrunc (LENGTH('a)) (numeral bin))" |
598 by (simp only: unat_def uint_bintrunc) |
598 by (simp only: unat_def uint_bintrunc) |
599 |
599 |
600 lemma unat_bintrunc_neg [simp]: |
600 lemma unat_bintrunc_neg [simp]: |
601 "unat (- numeral bin :: 'a::len0 word) = nat (bintrunc (len_of TYPE('a)) (- numeral bin))" |
601 "unat (- numeral bin :: 'a::len0 word) = nat (bintrunc (LENGTH('a)) (- numeral bin))" |
602 by (simp only: unat_def uint_bintrunc_neg) |
602 by (simp only: unat_def uint_bintrunc_neg) |
603 |
603 |
604 lemma size_0_eq: "size w = 0 \<Longrightarrow> v = w" |
604 lemma size_0_eq: "size w = 0 \<Longrightarrow> v = w" |
605 for v w :: "'a::len0 word" |
605 for v w :: "'a::len0 word" |
606 apply (unfold word_size) |
606 apply (unfold word_size) |
613 |
613 |
614 lemma uint_ge_0 [iff]: "0 \<le> uint x" |
614 lemma uint_ge_0 [iff]: "0 \<le> uint x" |
615 for x :: "'a::len0 word" |
615 for x :: "'a::len0 word" |
616 using word_uint.Rep [of x] by (simp add: uints_num) |
616 using word_uint.Rep [of x] by (simp add: uints_num) |
617 |
617 |
618 lemma uint_lt2p [iff]: "uint x < 2 ^ len_of TYPE('a)" |
618 lemma uint_lt2p [iff]: "uint x < 2 ^ LENGTH('a)" |
619 for x :: "'a::len0 word" |
619 for x :: "'a::len0 word" |
620 using word_uint.Rep [of x] by (simp add: uints_num) |
620 using word_uint.Rep [of x] by (simp add: uints_num) |
621 |
621 |
622 lemma sint_ge: "- (2 ^ (len_of TYPE('a) - 1)) \<le> sint x" |
622 lemma sint_ge: "- (2 ^ (LENGTH('a) - 1)) \<le> sint x" |
623 for x :: "'a::len word" |
623 for x :: "'a::len word" |
624 using word_sint.Rep [of x] by (simp add: sints_num) |
624 using word_sint.Rep [of x] by (simp add: sints_num) |
625 |
625 |
626 lemma sint_lt: "sint x < 2 ^ (len_of TYPE('a) - 1)" |
626 lemma sint_lt: "sint x < 2 ^ (LENGTH('a) - 1)" |
627 for x :: "'a::len word" |
627 for x :: "'a::len word" |
628 using word_sint.Rep [of x] by (simp add: sints_num) |
628 using word_sint.Rep [of x] by (simp add: sints_num) |
629 |
629 |
630 lemma sign_uint_Pls [simp]: "bin_sign (uint x) = 0" |
630 lemma sign_uint_Pls [simp]: "bin_sign (uint x) = 0" |
631 by (simp add: sign_Pls_ge_0) |
631 by (simp add: sign_Pls_ge_0) |
632 |
632 |
633 lemma uint_m2p_neg: "uint x - 2 ^ len_of TYPE('a) < 0" |
633 lemma uint_m2p_neg: "uint x - 2 ^ LENGTH('a) < 0" |
634 for x :: "'a::len0 word" |
634 for x :: "'a::len0 word" |
635 by (simp only: diff_less_0_iff_less uint_lt2p) |
635 by (simp only: diff_less_0_iff_less uint_lt2p) |
636 |
636 |
637 lemma uint_m2p_not_non_neg: "\<not> 0 \<le> uint x - 2 ^ len_of TYPE('a)" |
637 lemma uint_m2p_not_non_neg: "\<not> 0 \<le> uint x - 2 ^ LENGTH('a)" |
638 for x :: "'a::len0 word" |
638 for x :: "'a::len0 word" |
639 by (simp only: not_le uint_m2p_neg) |
639 by (simp only: not_le uint_m2p_neg) |
640 |
640 |
641 lemma lt2p_lem: "len_of TYPE('a) \<le> n \<Longrightarrow> uint w < 2 ^ n" |
641 lemma lt2p_lem: "LENGTH('a) \<le> n \<Longrightarrow> uint w < 2 ^ n" |
642 for w :: "'a::len0 word" |
642 for w :: "'a::len0 word" |
643 by (metis bintr_uint bintrunc_mod2p int_mod_lem zless2p) |
643 by (metis bintr_uint bintrunc_mod2p int_mod_lem zless2p) |
644 |
644 |
645 lemma uint_le_0_iff [simp]: "uint x \<le> 0 \<longleftrightarrow> uint x = 0" |
645 lemma uint_le_0_iff [simp]: "uint x \<le> 0 \<longleftrightarrow> uint x = 0" |
646 by (fact uint_ge_0 [THEN leD, THEN linorder_antisym_conv1]) |
646 by (fact uint_ge_0 [THEN leD, THEN linorder_antisym_conv1]) |
647 |
647 |
648 lemma uint_nat: "uint w = int (unat w)" |
648 lemma uint_nat: "uint w = int (unat w)" |
649 by (auto simp: unat_def) |
649 by (auto simp: unat_def) |
650 |
650 |
651 lemma uint_numeral: "uint (numeral b :: 'a::len0 word) = numeral b mod 2 ^ len_of TYPE('a)" |
651 lemma uint_numeral: "uint (numeral b :: 'a::len0 word) = numeral b mod 2 ^ LENGTH('a)" |
652 by (simp only: word_numeral_alt int_word_uint) |
652 by (simp only: word_numeral_alt int_word_uint) |
653 |
653 |
654 lemma uint_neg_numeral: "uint (- numeral b :: 'a::len0 word) = - numeral b mod 2 ^ len_of TYPE('a)" |
654 lemma uint_neg_numeral: "uint (- numeral b :: 'a::len0 word) = - numeral b mod 2 ^ LENGTH('a)" |
655 by (simp only: word_neg_numeral_alt int_word_uint) |
655 by (simp only: word_neg_numeral_alt int_word_uint) |
656 |
656 |
657 lemma unat_numeral: "unat (numeral b :: 'a::len0 word) = numeral b mod 2 ^ len_of TYPE('a)" |
657 lemma unat_numeral: "unat (numeral b :: 'a::len0 word) = numeral b mod 2 ^ LENGTH('a)" |
658 apply (unfold unat_def) |
658 apply (unfold unat_def) |
659 apply (clarsimp simp only: uint_numeral) |
659 apply (clarsimp simp only: uint_numeral) |
660 apply (rule nat_mod_distrib [THEN trans]) |
660 apply (rule nat_mod_distrib [THEN trans]) |
661 apply (rule zero_le_numeral) |
661 apply (rule zero_le_numeral) |
662 apply (simp_all add: nat_power_eq) |
662 apply (simp_all add: nat_power_eq) |
663 done |
663 done |
664 |
664 |
665 lemma sint_numeral: |
665 lemma sint_numeral: |
666 "sint (numeral b :: 'a::len word) = |
666 "sint (numeral b :: 'a::len word) = |
667 (numeral b + |
667 (numeral b + |
668 2 ^ (len_of TYPE('a) - 1)) mod 2 ^ len_of TYPE('a) - |
668 2 ^ (LENGTH('a) - 1)) mod 2 ^ LENGTH('a) - |
669 2 ^ (len_of TYPE('a) - 1)" |
669 2 ^ (LENGTH('a) - 1)" |
670 unfolding word_numeral_alt by (rule int_word_sint) |
670 unfolding word_numeral_alt by (rule int_word_sint) |
671 |
671 |
672 lemma word_of_int_0 [simp, code_post]: "word_of_int 0 = 0" |
672 lemma word_of_int_0 [simp, code_post]: "word_of_int 0 = 0" |
673 unfolding word_0_wi .. |
673 unfolding word_0_wi .. |
674 |
674 |
684 lemma word_of_int_neg_numeral [simp]: |
684 lemma word_of_int_neg_numeral [simp]: |
685 "(word_of_int (- numeral bin) :: 'a::len0 word) = - numeral bin" |
685 "(word_of_int (- numeral bin) :: 'a::len0 word) = - numeral bin" |
686 by (simp only: word_numeral_alt wi_hom_syms) |
686 by (simp only: word_numeral_alt wi_hom_syms) |
687 |
687 |
688 lemma word_int_case_wi: |
688 lemma word_int_case_wi: |
689 "word_int_case f (word_of_int i :: 'b word) = f (i mod 2 ^ len_of TYPE('b::len0))" |
689 "word_int_case f (word_of_int i :: 'b word) = f (i mod 2 ^ LENGTH('b::len0))" |
690 by (simp add: word_int_case_def word_uint.eq_norm) |
690 by (simp add: word_int_case_def word_uint.eq_norm) |
691 |
691 |
692 lemma word_int_split: |
692 lemma word_int_split: |
693 "P (word_int_case f x) = |
693 "P (word_int_case f x) = |
694 (\<forall>i. x = (word_of_int i :: 'b::len0 word) \<and> 0 \<le> i \<and> i < 2 ^ len_of TYPE('b) \<longrightarrow> P (f i))" |
694 (\<forall>i. x = (word_of_int i :: 'b::len0 word) \<and> 0 \<le> i \<and> i < 2 ^ LENGTH('b) \<longrightarrow> P (f i))" |
695 by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial) |
695 by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial) |
696 |
696 |
697 lemma word_int_split_asm: |
697 lemma word_int_split_asm: |
698 "P (word_int_case f x) = |
698 "P (word_int_case f x) = |
699 (\<nexists>n. x = (word_of_int n :: 'b::len0 word) \<and> 0 \<le> n \<and> n < 2 ^ len_of TYPE('b::len0) \<and> \<not> P (f n))" |
699 (\<nexists>n. x = (word_of_int n :: 'b::len0 word) \<and> 0 \<le> n \<and> n < 2 ^ LENGTH('b::len0) \<and> \<not> P (f n))" |
700 by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial) |
700 by (auto simp: word_int_case_def word_uint.eq_norm mod_pos_pos_trivial) |
701 |
701 |
702 lemmas uint_range' = word_uint.Rep [unfolded uints_num mem_Collect_eq] |
702 lemmas uint_range' = word_uint.Rep [unfolded uints_num mem_Collect_eq] |
703 lemmas sint_range' = word_sint.Rep [unfolded One_nat_def sints_num mem_Collect_eq] |
703 lemmas sint_range' = word_sint.Rep [unfolded One_nat_def sints_num mem_Collect_eq] |
704 |
704 |
747 lemma test_bit_bin': "w !! n \<longleftrightarrow> n < size w \<and> bin_nth (uint w) n" |
747 lemma test_bit_bin': "w !! n \<longleftrightarrow> n < size w \<and> bin_nth (uint w) n" |
748 by (simp add: word_test_bit_def word_size nth_bintr [symmetric]) |
748 by (simp add: word_test_bit_def word_size nth_bintr [symmetric]) |
749 |
749 |
750 lemmas test_bit_bin = test_bit_bin' [unfolded word_size] |
750 lemmas test_bit_bin = test_bit_bin' [unfolded word_size] |
751 |
751 |
752 lemma bin_nth_uint_imp: "bin_nth (uint w) n \<Longrightarrow> n < len_of TYPE('a)" |
752 lemma bin_nth_uint_imp: "bin_nth (uint w) n \<Longrightarrow> n < LENGTH('a)" |
753 for w :: "'a::len0 word" |
753 for w :: "'a::len0 word" |
754 apply (rule nth_bintr [THEN iffD1, THEN conjunct1]) |
754 apply (rule nth_bintr [THEN iffD1, THEN conjunct1]) |
755 apply (subst word_ubin.norm_Rep) |
755 apply (subst word_ubin.norm_Rep) |
756 apply assumption |
756 apply assumption |
757 done |
757 done |
758 |
758 |
759 lemma bin_nth_sint: |
759 lemma bin_nth_sint: |
760 "len_of TYPE('a) \<le> n \<Longrightarrow> |
760 "LENGTH('a) \<le> n \<Longrightarrow> |
761 bin_nth (sint w) n = bin_nth (sint w) (len_of TYPE('a) - 1)" |
761 bin_nth (sint w) n = bin_nth (sint w) (LENGTH('a) - 1)" |
762 for w :: "'a::len word" |
762 for w :: "'a::len word" |
763 apply (subst word_sbin.norm_Rep [symmetric]) |
763 apply (subst word_sbin.norm_Rep [symmetric]) |
764 apply (auto simp add: nth_sbintr) |
764 apply (auto simp add: nth_sbintr) |
765 done |
765 done |
766 |
766 |
767 \<comment> \<open>type definitions theorem for in terms of equivalent bool list\<close> |
767 \<comment> \<open>type definitions theorem for in terms of equivalent bool list\<close> |
768 lemma td_bl: |
768 lemma td_bl: |
769 "type_definition |
769 "type_definition |
770 (to_bl :: 'a::len0 word \<Rightarrow> bool list) |
770 (to_bl :: 'a::len0 word \<Rightarrow> bool list) |
771 of_bl |
771 of_bl |
772 {bl. length bl = len_of TYPE('a)}" |
772 {bl. length bl = LENGTH('a)}" |
773 apply (unfold type_definition_def of_bl_def to_bl_def) |
773 apply (unfold type_definition_def of_bl_def to_bl_def) |
774 apply (simp add: word_ubin.eq_norm) |
774 apply (simp add: word_ubin.eq_norm) |
775 apply safe |
775 apply safe |
776 apply (drule sym) |
776 apply (drule sym) |
777 apply simp |
777 apply simp |
821 apply (rule trans [OF _ bl_sbin_sign]) |
821 apply (rule trans [OF _ bl_sbin_sign]) |
822 apply simp |
822 apply simp |
823 done |
823 done |
824 |
824 |
825 lemma of_bl_drop': |
825 lemma of_bl_drop': |
826 "lend = length bl - len_of TYPE('a::len0) \<Longrightarrow> |
826 "lend = length bl - LENGTH('a::len0) \<Longrightarrow> |
827 of_bl (drop lend bl) = (of_bl bl :: 'a word)" |
827 of_bl (drop lend bl) = (of_bl bl :: 'a word)" |
828 by (auto simp: of_bl_def trunc_bl2bin [symmetric]) |
828 by (auto simp: of_bl_def trunc_bl2bin [symmetric]) |
829 |
829 |
830 lemma test_bit_of_bl: |
830 lemma test_bit_of_bl: |
831 "(of_bl bl::'a::len0 word) !! n = (rev bl ! n \<and> n < len_of TYPE('a) \<and> n < length bl)" |
831 "(of_bl bl::'a::len0 word) !! n = (rev bl ! n \<and> n < LENGTH('a) \<and> n < length bl)" |
832 by (auto simp add: of_bl_def word_test_bit_def word_size |
832 by (auto simp add: of_bl_def word_test_bit_def word_size |
833 word_ubin.eq_norm nth_bintr bin_nth_of_bl) |
833 word_ubin.eq_norm nth_bintr bin_nth_of_bl) |
834 |
834 |
835 lemma no_of_bl: "(numeral bin ::'a::len0 word) = of_bl (bin_to_bl (len_of TYPE('a)) (numeral bin))" |
835 lemma no_of_bl: "(numeral bin ::'a::len0 word) = of_bl (bin_to_bl (LENGTH('a)) (numeral bin))" |
836 by (simp add: of_bl_def) |
836 by (simp add: of_bl_def) |
837 |
837 |
838 lemma uint_bl: "to_bl w = bin_to_bl (size w) (uint w)" |
838 lemma uint_bl: "to_bl w = bin_to_bl (size w) (uint w)" |
839 by (auto simp: word_size to_bl_def) |
839 by (auto simp: word_size to_bl_def) |
840 |
840 |
841 lemma to_bl_bin: "bl_to_bin (to_bl w) = uint w" |
841 lemma to_bl_bin: "bl_to_bin (to_bl w) = uint w" |
842 by (simp add: uint_bl word_size) |
842 by (simp add: uint_bl word_size) |
843 |
843 |
844 lemma to_bl_of_bin: "to_bl (word_of_int bin::'a::len0 word) = bin_to_bl (len_of TYPE('a)) bin" |
844 lemma to_bl_of_bin: "to_bl (word_of_int bin::'a::len0 word) = bin_to_bl (LENGTH('a)) bin" |
845 by (auto simp: uint_bl word_ubin.eq_norm word_size) |
845 by (auto simp: uint_bl word_ubin.eq_norm word_size) |
846 |
846 |
847 lemma to_bl_numeral [simp]: |
847 lemma to_bl_numeral [simp]: |
848 "to_bl (numeral bin::'a::len0 word) = |
848 "to_bl (numeral bin::'a::len0 word) = |
849 bin_to_bl (len_of TYPE('a)) (numeral bin)" |
849 bin_to_bl (LENGTH('a)) (numeral bin)" |
850 unfolding word_numeral_alt by (rule to_bl_of_bin) |
850 unfolding word_numeral_alt by (rule to_bl_of_bin) |
851 |
851 |
852 lemma to_bl_neg_numeral [simp]: |
852 lemma to_bl_neg_numeral [simp]: |
853 "to_bl (- numeral bin::'a::len0 word) = |
853 "to_bl (- numeral bin::'a::len0 word) = |
854 bin_to_bl (len_of TYPE('a)) (- numeral bin)" |
854 bin_to_bl (LENGTH('a)) (- numeral bin)" |
855 unfolding word_neg_numeral_alt by (rule to_bl_of_bin) |
855 unfolding word_neg_numeral_alt by (rule to_bl_of_bin) |
856 |
856 |
857 lemma to_bl_to_bin [simp] : "bl_to_bin (to_bl w) = uint w" |
857 lemma to_bl_to_bin [simp] : "bl_to_bin (to_bl w) = uint w" |
858 by (simp add: uint_bl word_size) |
858 by (simp add: uint_bl word_size) |
859 |
859 |
860 lemma uint_bl_bin: "bl_to_bin (bin_to_bl (len_of TYPE('a)) (uint x)) = uint x" |
860 lemma uint_bl_bin: "bl_to_bin (bin_to_bl (LENGTH('a)) (uint x)) = uint x" |
861 for x :: "'a::len0 word" |
861 for x :: "'a::len0 word" |
862 by (rule trans [OF bin_bl_bin word_ubin.norm_Rep]) |
862 by (rule trans [OF bin_bl_bin word_ubin.norm_Rep]) |
863 |
863 |
864 \<comment> \<open>naturals\<close> |
864 \<comment> \<open>naturals\<close> |
865 lemma uints_unats: "uints n = int ` unats n" |
865 lemma uints_unats: "uints n = int ` unats n" |
876 word_ubin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b |
876 word_ubin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b |
877 lemmas sbintr_num = |
877 lemmas sbintr_num = |
878 word_sbin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b |
878 word_sbin.norm_eq_iff [of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b |
879 |
879 |
880 lemma num_of_bintr': |
880 lemma num_of_bintr': |
881 "bintrunc (len_of TYPE('a::len0)) (numeral a) = (numeral b) \<Longrightarrow> |
881 "bintrunc (LENGTH('a::len0)) (numeral a) = (numeral b) \<Longrightarrow> |
882 numeral a = (numeral b :: 'a word)" |
882 numeral a = (numeral b :: 'a word)" |
883 unfolding bintr_num by (erule subst, simp) |
883 unfolding bintr_num by (erule subst, simp) |
884 |
884 |
885 lemma num_of_sbintr': |
885 lemma num_of_sbintr': |
886 "sbintrunc (len_of TYPE('a::len) - 1) (numeral a) = (numeral b) \<Longrightarrow> |
886 "sbintrunc (LENGTH('a::len) - 1) (numeral a) = (numeral b) \<Longrightarrow> |
887 numeral a = (numeral b :: 'a word)" |
887 numeral a = (numeral b :: 'a word)" |
888 unfolding sbintr_num by (erule subst, simp) |
888 unfolding sbintr_num by (erule subst, simp) |
889 |
889 |
890 lemma num_abs_bintr: |
890 lemma num_abs_bintr: |
891 "(numeral x :: 'a word) = |
891 "(numeral x :: 'a word) = |
892 word_of_int (bintrunc (len_of TYPE('a::len0)) (numeral x))" |
892 word_of_int (bintrunc (LENGTH('a::len0)) (numeral x))" |
893 by (simp only: word_ubin.Abs_norm word_numeral_alt) |
893 by (simp only: word_ubin.Abs_norm word_numeral_alt) |
894 |
894 |
895 lemma num_abs_sbintr: |
895 lemma num_abs_sbintr: |
896 "(numeral x :: 'a word) = |
896 "(numeral x :: 'a word) = |
897 word_of_int (sbintrunc (len_of TYPE('a::len) - 1) (numeral x))" |
897 word_of_int (sbintrunc (LENGTH('a::len) - 1) (numeral x))" |
898 by (simp only: word_sbin.Abs_norm word_numeral_alt) |
898 by (simp only: word_sbin.Abs_norm word_numeral_alt) |
899 |
899 |
900 text \<open> |
900 text \<open> |
901 \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result, |
901 \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result, |
902 thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>! |
902 thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>! |
909 by (auto simp: scast_def) |
909 by (auto simp: scast_def) |
910 |
910 |
911 lemma ucast_bl: "ucast w = of_bl (to_bl w)" |
911 lemma ucast_bl: "ucast w = of_bl (to_bl w)" |
912 by (auto simp: ucast_def of_bl_def uint_bl word_size) |
912 by (auto simp: ucast_def of_bl_def uint_bl word_size) |
913 |
913 |
914 lemma nth_ucast: "(ucast w::'a::len0 word) !! n = (w !! n \<and> n < len_of TYPE('a))" |
914 lemma nth_ucast: "(ucast w::'a::len0 word) !! n = (w !! n \<and> n < LENGTH('a))" |
915 by (simp add: ucast_def test_bit_bin word_ubin.eq_norm nth_bintr word_size) |
915 by (simp add: ucast_def test_bit_bin word_ubin.eq_norm nth_bintr word_size) |
916 (fast elim!: bin_nth_uint_imp) |
916 (fast elim!: bin_nth_uint_imp) |
917 |
917 |
918 \<comment> \<open>literal u(s)cast\<close> |
918 \<comment> \<open>literal u(s)cast\<close> |
919 lemma ucast_bintr [simp]: |
919 lemma ucast_bintr [simp]: |
920 "ucast (numeral w :: 'a::len0 word) = |
920 "ucast (numeral w :: 'a::len0 word) = |
921 word_of_int (bintrunc (len_of TYPE('a)) (numeral w))" |
921 word_of_int (bintrunc (LENGTH('a)) (numeral w))" |
922 by (simp add: ucast_def) |
922 by (simp add: ucast_def) |
923 |
923 |
924 (* TODO: neg_numeral *) |
924 (* TODO: neg_numeral *) |
925 |
925 |
926 lemma scast_sbintr [simp]: |
926 lemma scast_sbintr [simp]: |
927 "scast (numeral w ::'a::len word) = |
927 "scast (numeral w ::'a::len word) = |
928 word_of_int (sbintrunc (len_of TYPE('a) - Suc 0) (numeral w))" |
928 word_of_int (sbintrunc (LENGTH('a) - Suc 0) (numeral w))" |
929 by (simp add: scast_def) |
929 by (simp add: scast_def) |
930 |
930 |
931 lemma source_size: "source_size (c::'a::len0 word \<Rightarrow> _) = len_of TYPE('a)" |
931 lemma source_size: "source_size (c::'a::len0 word \<Rightarrow> _) = LENGTH('a)" |
932 unfolding source_size_def word_size Let_def .. |
932 unfolding source_size_def word_size Let_def .. |
933 |
933 |
934 lemma target_size: "target_size (c::_ \<Rightarrow> 'b::len0 word) = len_of TYPE('b)" |
934 lemma target_size: "target_size (c::_ \<Rightarrow> 'b::len0 word) = LENGTH('b)" |
935 unfolding target_size_def word_size Let_def .. |
935 unfolding target_size_def word_size Let_def .. |
936 |
936 |
937 lemma is_down: "is_down c \<longleftrightarrow> len_of TYPE('b) \<le> len_of TYPE('a)" |
937 lemma is_down: "is_down c \<longleftrightarrow> LENGTH('b) \<le> LENGTH('a)" |
938 for c :: "'a::len0 word \<Rightarrow> 'b::len0 word" |
938 for c :: "'a::len0 word \<Rightarrow> 'b::len0 word" |
939 by (simp only: is_down_def source_size target_size) |
939 by (simp only: is_down_def source_size target_size) |
940 |
940 |
941 lemma is_up: "is_up c \<longleftrightarrow> len_of TYPE('a) \<le> len_of TYPE('b)" |
941 lemma is_up: "is_up c \<longleftrightarrow> LENGTH('a) \<le> LENGTH('b)" |
942 for c :: "'a::len0 word \<Rightarrow> 'b::len0 word" |
942 for c :: "'a::len0 word \<Rightarrow> 'b::len0 word" |
943 by (simp only: is_up_def source_size target_size) |
943 by (simp only: is_up_def source_size target_size) |
944 |
944 |
945 lemmas is_up_down = trans [OF is_up is_down [symmetric]] |
945 lemmas is_up_down = trans [OF is_up is_down [symmetric]] |
946 |
946 |
953 apply simp |
953 apply simp |
954 done |
954 done |
955 |
955 |
956 lemma word_rev_tf: |
956 lemma word_rev_tf: |
957 "to_bl (of_bl bl::'a::len0 word) = |
957 "to_bl (of_bl bl::'a::len0 word) = |
958 rev (takefill False (len_of TYPE('a)) (rev bl))" |
958 rev (takefill False (LENGTH('a)) (rev bl))" |
959 by (auto simp: of_bl_def uint_bl bl_bin_bl_rtf word_ubin.eq_norm word_size) |
959 by (auto simp: of_bl_def uint_bl bl_bin_bl_rtf word_ubin.eq_norm word_size) |
960 |
960 |
961 lemma word_rep_drop: |
961 lemma word_rep_drop: |
962 "to_bl (of_bl bl::'a::len0 word) = |
962 "to_bl (of_bl bl::'a::len0 word) = |
963 replicate (len_of TYPE('a) - length bl) False @ |
963 replicate (LENGTH('a) - length bl) False @ |
964 drop (length bl - len_of TYPE('a)) bl" |
964 drop (length bl - LENGTH('a)) bl" |
965 by (simp add: word_rev_tf takefill_alt rev_take) |
965 by (simp add: word_rev_tf takefill_alt rev_take) |
966 |
966 |
967 lemma to_bl_ucast: |
967 lemma to_bl_ucast: |
968 "to_bl (ucast (w::'b::len0 word) ::'a::len0 word) = |
968 "to_bl (ucast (w::'b::len0 word) ::'a::len0 word) = |
969 replicate (len_of TYPE('a) - len_of TYPE('b)) False @ |
969 replicate (LENGTH('a) - LENGTH('b)) False @ |
970 drop (len_of TYPE('b) - len_of TYPE('a)) (to_bl w)" |
970 drop (LENGTH('b) - LENGTH('a)) (to_bl w)" |
971 apply (unfold ucast_bl) |
971 apply (unfold ucast_bl) |
972 apply (rule trans) |
972 apply (rule trans) |
973 apply (rule word_rep_drop) |
973 apply (rule word_rep_drop) |
974 apply simp |
974 apply simp |
975 done |
975 done |
1187 lemma uint_cong: "x = y \<Longrightarrow> uint x = uint y" |
1187 lemma uint_cong: "x = y \<Longrightarrow> uint x = uint y" |
1188 by simp |
1188 by simp |
1189 |
1189 |
1190 lemma uint_word_ariths: |
1190 lemma uint_word_ariths: |
1191 fixes a b :: "'a::len0 word" |
1191 fixes a b :: "'a::len0 word" |
1192 shows "uint (a + b) = (uint a + uint b) mod 2 ^ len_of TYPE('a::len0)" |
1192 shows "uint (a + b) = (uint a + uint b) mod 2 ^ LENGTH('a::len0)" |
1193 and "uint (a - b) = (uint a - uint b) mod 2 ^ len_of TYPE('a)" |
1193 and "uint (a - b) = (uint a - uint b) mod 2 ^ LENGTH('a)" |
1194 and "uint (a * b) = uint a * uint b mod 2 ^ len_of TYPE('a)" |
1194 and "uint (a * b) = uint a * uint b mod 2 ^ LENGTH('a)" |
1195 and "uint (- a) = - uint a mod 2 ^ len_of TYPE('a)" |
1195 and "uint (- a) = - uint a mod 2 ^ LENGTH('a)" |
1196 and "uint (word_succ a) = (uint a + 1) mod 2 ^ len_of TYPE('a)" |
1196 and "uint (word_succ a) = (uint a + 1) mod 2 ^ LENGTH('a)" |
1197 and "uint (word_pred a) = (uint a - 1) mod 2 ^ len_of TYPE('a)" |
1197 and "uint (word_pred a) = (uint a - 1) mod 2 ^ LENGTH('a)" |
1198 and "uint (0 :: 'a word) = 0 mod 2 ^ len_of TYPE('a)" |
1198 and "uint (0 :: 'a word) = 0 mod 2 ^ LENGTH('a)" |
1199 and "uint (1 :: 'a word) = 1 mod 2 ^ len_of TYPE('a)" |
1199 and "uint (1 :: 'a word) = 1 mod 2 ^ LENGTH('a)" |
1200 by (simp_all add: word_arith_wis [THEN trans [OF uint_cong int_word_uint]]) |
1200 by (simp_all add: word_arith_wis [THEN trans [OF uint_cong int_word_uint]]) |
1201 |
1201 |
1202 lemma uint_word_arith_bintrs: |
1202 lemma uint_word_arith_bintrs: |
1203 fixes a b :: "'a::len0 word" |
1203 fixes a b :: "'a::len0 word" |
1204 shows "uint (a + b) = bintrunc (len_of TYPE('a)) (uint a + uint b)" |
1204 shows "uint (a + b) = bintrunc (LENGTH('a)) (uint a + uint b)" |
1205 and "uint (a - b) = bintrunc (len_of TYPE('a)) (uint a - uint b)" |
1205 and "uint (a - b) = bintrunc (LENGTH('a)) (uint a - uint b)" |
1206 and "uint (a * b) = bintrunc (len_of TYPE('a)) (uint a * uint b)" |
1206 and "uint (a * b) = bintrunc (LENGTH('a)) (uint a * uint b)" |
1207 and "uint (- a) = bintrunc (len_of TYPE('a)) (- uint a)" |
1207 and "uint (- a) = bintrunc (LENGTH('a)) (- uint a)" |
1208 and "uint (word_succ a) = bintrunc (len_of TYPE('a)) (uint a + 1)" |
1208 and "uint (word_succ a) = bintrunc (LENGTH('a)) (uint a + 1)" |
1209 and "uint (word_pred a) = bintrunc (len_of TYPE('a)) (uint a - 1)" |
1209 and "uint (word_pred a) = bintrunc (LENGTH('a)) (uint a - 1)" |
1210 and "uint (0 :: 'a word) = bintrunc (len_of TYPE('a)) 0" |
1210 and "uint (0 :: 'a word) = bintrunc (LENGTH('a)) 0" |
1211 and "uint (1 :: 'a word) = bintrunc (len_of TYPE('a)) 1" |
1211 and "uint (1 :: 'a word) = bintrunc (LENGTH('a)) 1" |
1212 by (simp_all add: uint_word_ariths bintrunc_mod2p) |
1212 by (simp_all add: uint_word_ariths bintrunc_mod2p) |
1213 |
1213 |
1214 lemma sint_word_ariths: |
1214 lemma sint_word_ariths: |
1215 fixes a b :: "'a::len word" |
1215 fixes a b :: "'a::len word" |
1216 shows "sint (a + b) = sbintrunc (len_of TYPE('a) - 1) (sint a + sint b)" |
1216 shows "sint (a + b) = sbintrunc (LENGTH('a) - 1) (sint a + sint b)" |
1217 and "sint (a - b) = sbintrunc (len_of TYPE('a) - 1) (sint a - sint b)" |
1217 and "sint (a - b) = sbintrunc (LENGTH('a) - 1) (sint a - sint b)" |
1218 and "sint (a * b) = sbintrunc (len_of TYPE('a) - 1) (sint a * sint b)" |
1218 and "sint (a * b) = sbintrunc (LENGTH('a) - 1) (sint a * sint b)" |
1219 and "sint (- a) = sbintrunc (len_of TYPE('a) - 1) (- sint a)" |
1219 and "sint (- a) = sbintrunc (LENGTH('a) - 1) (- sint a)" |
1220 and "sint (word_succ a) = sbintrunc (len_of TYPE('a) - 1) (sint a + 1)" |
1220 and "sint (word_succ a) = sbintrunc (LENGTH('a) - 1) (sint a + 1)" |
1221 and "sint (word_pred a) = sbintrunc (len_of TYPE('a) - 1) (sint a - 1)" |
1221 and "sint (word_pred a) = sbintrunc (LENGTH('a) - 1) (sint a - 1)" |
1222 and "sint (0 :: 'a word) = sbintrunc (len_of TYPE('a) - 1) 0" |
1222 and "sint (0 :: 'a word) = sbintrunc (LENGTH('a) - 1) 0" |
1223 and "sint (1 :: 'a word) = sbintrunc (len_of TYPE('a) - 1) 1" |
1223 and "sint (1 :: 'a word) = sbintrunc (LENGTH('a) - 1) 1" |
1224 apply (simp_all only: word_sbin.inverse_norm [symmetric]) |
1224 apply (simp_all only: word_sbin.inverse_norm [symmetric]) |
1225 apply (simp_all add: wi_hom_syms) |
1225 apply (simp_all add: wi_hom_syms) |
1226 apply transfer apply simp |
1226 apply transfer apply simp |
1227 apply transfer apply simp |
1227 apply transfer apply simp |
1228 done |
1228 done |
1282 unfolding unat_def word_less_alt |
1282 unfolding unat_def word_less_alt |
1283 by (rule nat_less_eq_zless [symmetric]) simp |
1283 by (rule nat_less_eq_zless [symmetric]) simp |
1284 |
1284 |
1285 lemma wi_less: |
1285 lemma wi_less: |
1286 "(word_of_int n < (word_of_int m :: 'a::len0 word)) = |
1286 "(word_of_int n < (word_of_int m :: 'a::len0 word)) = |
1287 (n mod 2 ^ len_of TYPE('a) < m mod 2 ^ len_of TYPE('a))" |
1287 (n mod 2 ^ LENGTH('a) < m mod 2 ^ LENGTH('a))" |
1288 unfolding word_less_alt by (simp add: word_uint.eq_norm) |
1288 unfolding word_less_alt by (simp add: word_uint.eq_norm) |
1289 |
1289 |
1290 lemma wi_le: |
1290 lemma wi_le: |
1291 "(word_of_int n \<le> (word_of_int m :: 'a::len0 word)) = |
1291 "(word_of_int n \<le> (word_of_int m :: 'a::len0 word)) = |
1292 (n mod 2 ^ len_of TYPE('a) \<le> m mod 2 ^ len_of TYPE('a))" |
1292 (n mod 2 ^ LENGTH('a) \<le> m mod 2 ^ LENGTH('a))" |
1293 unfolding word_le_def by (simp add: word_uint.eq_norm) |
1293 unfolding word_le_def by (simp add: word_uint.eq_norm) |
1294 |
1294 |
1295 lemma udvd_nat_alt: "a udvd b \<longleftrightarrow> (\<exists>n\<ge>0. unat b = n * unat a)" |
1295 lemma udvd_nat_alt: "a udvd b \<longleftrightarrow> (\<exists>n\<ge>0. unat b = n * unat a)" |
1296 apply (unfold udvd_def) |
1296 apply (unfold udvd_def) |
1297 apply safe |
1297 apply safe |
1333 by (simp add: unat_minus_one) (simp add: unat_0_iff [symmetric]) |
1333 by (simp add: unat_minus_one) (simp add: unat_0_iff [symmetric]) |
1334 |
1334 |
1335 lemmas uint_add_ge0 [simp] = add_nonneg_nonneg [OF uint_ge_0 uint_ge_0] |
1335 lemmas uint_add_ge0 [simp] = add_nonneg_nonneg [OF uint_ge_0 uint_ge_0] |
1336 lemmas uint_mult_ge0 [simp] = mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0] |
1336 lemmas uint_mult_ge0 [simp] = mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0] |
1337 |
1337 |
1338 lemma uint_sub_lt2p [simp]: "uint x - uint y < 2 ^ len_of TYPE('a)" |
1338 lemma uint_sub_lt2p [simp]: "uint x - uint y < 2 ^ LENGTH('a)" |
1339 for x :: "'a::len0 word" and y :: "'b::len0 word" |
1339 for x :: "'a::len0 word" and y :: "'b::len0 word" |
1340 using uint_ge_0 [of y] uint_lt2p [of x] by arith |
1340 using uint_ge_0 [of y] uint_lt2p [of x] by arith |
1341 |
1341 |
1342 |
1342 |
1343 subsection \<open>Conditions for the addition (etc) of two words to overflow\<close> |
1343 subsection \<open>Conditions for the addition (etc) of two words to overflow\<close> |
1344 |
1344 |
1345 lemma uint_add_lem: |
1345 lemma uint_add_lem: |
1346 "(uint x + uint y < 2 ^ len_of TYPE('a)) = |
1346 "(uint x + uint y < 2 ^ LENGTH('a)) = |
1347 (uint (x + y) = uint x + uint y)" |
1347 (uint (x + y) = uint x + uint y)" |
1348 for x y :: "'a::len0 word" |
1348 for x y :: "'a::len0 word" |
1349 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
1349 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
1350 |
1350 |
1351 lemma uint_mult_lem: |
1351 lemma uint_mult_lem: |
1352 "(uint x * uint y < 2 ^ len_of TYPE('a)) = |
1352 "(uint x * uint y < 2 ^ LENGTH('a)) = |
1353 (uint (x * y) = uint x * uint y)" |
1353 (uint (x * y) = uint x * uint y)" |
1354 for x y :: "'a::len0 word" |
1354 for x y :: "'a::len0 word" |
1355 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
1355 by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem]) |
1356 |
1356 |
1357 lemma uint_sub_lem: "uint x \<ge> uint y \<longleftrightarrow> uint (x - y) = uint x - uint y" |
1357 lemma uint_sub_lem: "uint x \<ge> uint y \<longleftrightarrow> uint (x - y) = uint x - uint y" |
1383 by (auto intro: int_mod_eq) |
1383 by (auto intro: int_mod_eq) |
1384 |
1384 |
1385 lemma uint_sub_if': |
1385 lemma uint_sub_if': |
1386 "uint (a - b) = |
1386 "uint (a - b) = |
1387 (if uint b \<le> uint a then uint a - uint b |
1387 (if uint b \<le> uint a then uint a - uint b |
1388 else uint a - uint b + 2 ^ len_of TYPE('a))" |
1388 else uint a - uint b + 2 ^ LENGTH('a))" |
1389 for a b :: "'a::len0 word" |
1389 for a b :: "'a::len0 word" |
1390 using mod_sub_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths) |
1390 using mod_sub_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths) |
1391 |
1391 |
1392 |
1392 |
1393 subsection \<open>Definition of \<open>uint_arith\<close>\<close> |
1393 subsection \<open>Definition of \<open>uint_arith\<close>\<close> |
1394 |
1394 |
1395 lemma word_of_int_inverse: |
1395 lemma word_of_int_inverse: |
1396 "word_of_int r = a \<Longrightarrow> 0 \<le> r \<Longrightarrow> r < 2 ^ len_of TYPE('a) \<Longrightarrow> uint a = r" |
1396 "word_of_int r = a \<Longrightarrow> 0 \<le> r \<Longrightarrow> r < 2 ^ LENGTH('a) \<Longrightarrow> uint a = r" |
1397 for a :: "'a::len0 word" |
1397 for a :: "'a::len0 word" |
1398 apply (erule word_uint.Abs_inverse' [rotated]) |
1398 apply (erule word_uint.Abs_inverse' [rotated]) |
1399 apply (simp add: uints_num) |
1399 apply (simp add: uints_num) |
1400 done |
1400 done |
1401 |
1401 |
1402 lemma uint_split: |
1402 lemma uint_split: |
1403 "P (uint x) = (\<forall>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^len_of TYPE('a) \<longrightarrow> P i)" |
1403 "P (uint x) = (\<forall>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^LENGTH('a) \<longrightarrow> P i)" |
1404 for x :: "'a::len0 word" |
1404 for x :: "'a::len0 word" |
1405 apply (fold word_int_case_def) |
1405 apply (fold word_int_case_def) |
1406 apply (auto dest!: word_of_int_inverse simp: int_word_uint mod_pos_pos_trivial |
1406 apply (auto dest!: word_of_int_inverse simp: int_word_uint mod_pos_pos_trivial |
1407 split: word_int_split) |
1407 split: word_int_split) |
1408 done |
1408 done |
1409 |
1409 |
1410 lemma uint_split_asm: |
1410 lemma uint_split_asm: |
1411 "P (uint x) = (\<nexists>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^len_of TYPE('a) \<and> \<not> P i)" |
1411 "P (uint x) = (\<nexists>i. word_of_int i = x \<and> 0 \<le> i \<and> i < 2^LENGTH('a) \<and> \<not> P i)" |
1412 for x :: "'a::len0 word" |
1412 for x :: "'a::len0 word" |
1413 by (auto dest!: word_of_int_inverse |
1413 by (auto dest!: word_of_int_inverse |
1414 simp: int_word_uint mod_pos_pos_trivial |
1414 simp: int_word_uint mod_pos_pos_trivial |
1415 split: uint_split) |
1415 split: uint_split) |
1416 |
1416 |
1694 note that \<open>iszero_def\<close> is only for class \<open>comm_semiring_1_cancel\<close>, |
1694 note that \<open>iszero_def\<close> is only for class \<open>comm_semiring_1_cancel\<close>, |
1695 which requires word length \<open>\<ge> 1\<close>, ie \<open>'a::len word\<close> |
1695 which requires word length \<open>\<ge> 1\<close>, ie \<open>'a::len word\<close> |
1696 \<close> |
1696 \<close> |
1697 lemma iszero_word_no [simp]: |
1697 lemma iszero_word_no [simp]: |
1698 "iszero (numeral bin :: 'a::len word) = |
1698 "iszero (numeral bin :: 'a::len word) = |
1699 iszero (bintrunc (len_of TYPE('a)) (numeral bin))" |
1699 iszero (bintrunc (LENGTH('a)) (numeral bin))" |
1700 using word_ubin.norm_eq_iff [where 'a='a, of "numeral bin" 0] |
1700 using word_ubin.norm_eq_iff [where 'a='a, of "numeral bin" 0] |
1701 by (simp add: iszero_def [symmetric]) |
1701 by (simp add: iszero_def [symmetric]) |
1702 |
1702 |
1703 text \<open>Use \<open>iszero\<close> to simplify equalities between word numerals.\<close> |
1703 text \<open>Use \<open>iszero\<close> to simplify equalities between word numerals.\<close> |
1704 |
1704 |
1721 |
1721 |
1722 interpretation word_unat: |
1722 interpretation word_unat: |
1723 td_ext |
1723 td_ext |
1724 "unat::'a::len word \<Rightarrow> nat" |
1724 "unat::'a::len word \<Rightarrow> nat" |
1725 of_nat |
1725 of_nat |
1726 "unats (len_of TYPE('a::len))" |
1726 "unats (LENGTH('a::len))" |
1727 "\<lambda>i. i mod 2 ^ len_of TYPE('a::len)" |
1727 "\<lambda>i. i mod 2 ^ LENGTH('a::len)" |
1728 by (rule td_ext_unat) |
1728 by (rule td_ext_unat) |
1729 |
1729 |
1730 lemmas td_unat = word_unat.td_thm |
1730 lemmas td_unat = word_unat.td_thm |
1731 |
1731 |
1732 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq] |
1732 lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq] |
1733 |
1733 |
1734 lemma unat_le: "y \<le> unat z \<Longrightarrow> y \<in> unats (len_of TYPE('a))" |
1734 lemma unat_le: "y \<le> unat z \<Longrightarrow> y \<in> unats (LENGTH('a))" |
1735 for z :: "'a::len word" |
1735 for z :: "'a::len word" |
1736 apply (unfold unats_def) |
1736 apply (unfold unats_def) |
1737 apply clarsimp |
1737 apply clarsimp |
1738 apply (rule xtrans, rule unat_lt2p, assumption) |
1738 apply (rule xtrans, rule unat_lt2p, assumption) |
1739 done |
1739 done |
1740 |
1740 |
1741 lemma word_nchotomy: "\<forall>w :: 'a::len word. \<exists>n. w = of_nat n \<and> n < 2 ^ len_of TYPE('a)" |
1741 lemma word_nchotomy: "\<forall>w :: 'a::len word. \<exists>n. w = of_nat n \<and> n < 2 ^ LENGTH('a)" |
1742 apply (rule allI) |
1742 apply (rule allI) |
1743 apply (rule word_unat.Abs_cases) |
1743 apply (rule word_unat.Abs_cases) |
1744 apply (unfold unats_def) |
1744 apply (unfold unats_def) |
1745 apply auto |
1745 apply auto |
1746 done |
1746 done |
1747 |
1747 |
1748 lemma of_nat_eq: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ len_of TYPE('a))" |
1748 lemma of_nat_eq: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ LENGTH('a))" |
1749 for w :: "'a::len word" |
1749 for w :: "'a::len word" |
1750 using mod_div_mult_eq [of n "2 ^ LENGTH('a)", symmetric] |
1750 using mod_div_mult_eq [of n "2 ^ LENGTH('a)", symmetric] |
1751 by (auto simp add: word_unat.inverse_norm) |
1751 by (auto simp add: word_unat.inverse_norm) |
1752 |
1752 |
1753 lemma of_nat_eq_size: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ size w)" |
1753 lemma of_nat_eq_size: "of_nat n = w \<longleftrightarrow> (\<exists>q. n = unat w + q * 2 ^ size w)" |
1754 unfolding word_size by (rule of_nat_eq) |
1754 unfolding word_size by (rule of_nat_eq) |
1755 |
1755 |
1756 lemma of_nat_0: "of_nat m = (0::'a::len word) \<longleftrightarrow> (\<exists>q. m = q * 2 ^ len_of TYPE('a))" |
1756 lemma of_nat_0: "of_nat m = (0::'a::len word) \<longleftrightarrow> (\<exists>q. m = q * 2 ^ LENGTH('a))" |
1757 by (simp add: of_nat_eq) |
1757 by (simp add: of_nat_eq) |
1758 |
1758 |
1759 lemma of_nat_2p [simp]: "of_nat (2 ^ len_of TYPE('a)) = (0::'a::len word)" |
1759 lemma of_nat_2p [simp]: "of_nat (2 ^ LENGTH('a)) = (0::'a::len word)" |
1760 by (fact mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]]) |
1760 by (fact mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]]) |
1761 |
1761 |
1762 lemma of_nat_gt_0: "of_nat k \<noteq> 0 \<Longrightarrow> 0 < k" |
1762 lemma of_nat_gt_0: "of_nat k \<noteq> 0 \<Longrightarrow> 0 < k" |
1763 by (cases k) auto |
1763 by (cases k) auto |
1764 |
1764 |
1765 lemma of_nat_neq_0: "0 < k \<Longrightarrow> k < 2 ^ len_of TYPE('a::len) \<Longrightarrow> of_nat k \<noteq> (0 :: 'a word)" |
1765 lemma of_nat_neq_0: "0 < k \<Longrightarrow> k < 2 ^ LENGTH('a::len) \<Longrightarrow> of_nat k \<noteq> (0 :: 'a word)" |
1766 by (auto simp add : of_nat_0) |
1766 by (auto simp add : of_nat_0) |
1767 |
1767 |
1768 lemma Abs_fnat_hom_add: "of_nat a + of_nat b = of_nat (a + b)" |
1768 lemma Abs_fnat_hom_add: "of_nat a + of_nat b = of_nat (a + b)" |
1769 by simp |
1769 by simp |
1770 |
1770 |
1813 |
1813 |
1814 lemmas word_sub_less_iff = word_sub_le_iff |
1814 lemmas word_sub_less_iff = word_sub_le_iff |
1815 [unfolded linorder_not_less [symmetric] Not_eq_iff] |
1815 [unfolded linorder_not_less [symmetric] Not_eq_iff] |
1816 |
1816 |
1817 lemma unat_add_lem: |
1817 lemma unat_add_lem: |
1818 "unat x + unat y < 2 ^ len_of TYPE('a) \<longleftrightarrow> unat (x + y) = unat x + unat y" |
1818 "unat x + unat y < 2 ^ LENGTH('a) \<longleftrightarrow> unat (x + y) = unat x + unat y" |
1819 for x y :: "'a::len word" |
1819 for x y :: "'a::len word" |
1820 by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem]) |
1820 by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem]) |
1821 |
1821 |
1822 lemma unat_mult_lem: |
1822 lemma unat_mult_lem: |
1823 "unat x * unat y < 2 ^ len_of TYPE('a) \<longleftrightarrow> unat (x * y) = unat x * unat y" |
1823 "unat x * unat y < 2 ^ LENGTH('a) \<longleftrightarrow> unat (x * y) = unat x * unat y" |
1824 for x y :: "'a::len word" |
1824 for x y :: "'a::len word" |
1825 by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem]) |
1825 by (auto simp: unat_word_ariths intro!: trans [OF _ nat_mod_lem]) |
1826 |
1826 |
1827 lemmas unat_plus_if' = |
1827 lemmas unat_plus_if' = |
1828 trans [OF unat_word_ariths(1) mod_nat_add, simplified] |
1828 trans [OF unat_word_ariths(1) mod_nat_add, simplified] |
1883 for x y :: "'a::len word" |
1883 for x y :: "'a::len word" |
1884 by (simp add: uint_nat unat_mod zmod_int) |
1884 by (simp add: uint_nat unat_mod zmod_int) |
1885 |
1885 |
1886 text \<open>Definition of \<open>unat_arith\<close> tactic\<close> |
1886 text \<open>Definition of \<open>unat_arith\<close> tactic\<close> |
1887 |
1887 |
1888 lemma unat_split: "P (unat x) \<longleftrightarrow> (\<forall>n. of_nat n = x \<and> n < 2^len_of TYPE('a) \<longrightarrow> P n)" |
1888 lemma unat_split: "P (unat x) \<longleftrightarrow> (\<forall>n. of_nat n = x \<and> n < 2^LENGTH('a) \<longrightarrow> P n)" |
1889 for x :: "'a::len word" |
1889 for x :: "'a::len word" |
1890 by (auto simp: unat_of_nat) |
1890 by (auto simp: unat_of_nat) |
1891 |
1891 |
1892 lemma unat_split_asm: "P (unat x) \<longleftrightarrow> (\<nexists>n. of_nat n = x \<and> n < 2^len_of TYPE('a) \<and> \<not> P n)" |
1892 lemma unat_split_asm: "P (unat x) \<longleftrightarrow> (\<nexists>n. of_nat n = x \<and> n < 2^LENGTH('a) \<and> \<not> P n)" |
1893 for x :: "'a::len word" |
1893 for x :: "'a::len word" |
1894 by (auto simp: unat_of_nat) |
1894 by (auto simp: unat_of_nat) |
1895 |
1895 |
1896 lemmas of_nat_inverse = |
1896 lemmas of_nat_inverse = |
1897 word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified] |
1897 word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified] |
1945 no_plus_overflow_unat_size [unfolded word_size] |
1945 no_plus_overflow_unat_size [unfolded word_size] |
1946 |
1946 |
1947 lemmas unat_plus_simple = |
1947 lemmas unat_plus_simple = |
1948 trans [OF no_olen_add_nat unat_add_lem] |
1948 trans [OF no_olen_add_nat unat_add_lem] |
1949 |
1949 |
1950 lemma word_div_mult: "0 < y \<Longrightarrow> unat x * unat y < 2 ^ len_of TYPE('a) \<Longrightarrow> x * y div y = x" |
1950 lemma word_div_mult: "0 < y \<Longrightarrow> unat x * unat y < 2 ^ LENGTH('a) \<Longrightarrow> x * y div y = x" |
1951 for x y :: "'a::len word" |
1951 for x y :: "'a::len word" |
1952 apply unat_arith |
1952 apply unat_arith |
1953 apply clarsimp |
1953 apply clarsimp |
1954 apply (subst unat_mult_lem [THEN iffD1]) |
1954 apply (subst unat_mult_lem [THEN iffD1]) |
1955 apply auto |
1955 apply auto |
1956 done |
1956 done |
1957 |
1957 |
1958 lemma div_lt': "i \<le> k div x \<Longrightarrow> unat i * unat x < 2 ^ len_of TYPE('a)" |
1958 lemma div_lt': "i \<le> k div x \<Longrightarrow> unat i * unat x < 2 ^ LENGTH('a)" |
1959 for i k x :: "'a::len word" |
1959 for i k x :: "'a::len word" |
1960 apply unat_arith |
1960 apply unat_arith |
1961 apply clarsimp |
1961 apply clarsimp |
1962 apply (drule mult_le_mono1) |
1962 apply (drule mult_le_mono1) |
1963 apply (erule order_le_less_trans) |
1963 apply (erule order_le_less_trans) |
1982 apply (drule mult_le_mono1) |
1982 apply (drule mult_le_mono1) |
1983 apply (erule order_trans) |
1983 apply (erule order_trans) |
1984 apply (rule div_mult_le) |
1984 apply (rule div_mult_le) |
1985 done |
1985 done |
1986 |
1986 |
1987 lemma div_lt_uint': "i \<le> k div x \<Longrightarrow> uint i * uint x < 2 ^ len_of TYPE('a)" |
1987 lemma div_lt_uint': "i \<le> k div x \<Longrightarrow> uint i * uint x < 2 ^ LENGTH('a)" |
1988 for i k x :: "'a::len word" |
1988 for i k x :: "'a::len word" |
1989 apply (unfold uint_nat) |
1989 apply (unfold uint_nat) |
1990 apply (drule div_lt') |
1990 apply (drule div_lt') |
1991 apply (metis of_nat_less_iff of_nat_mult of_nat_numeral of_nat_power) |
1991 apply (metis of_nat_less_iff of_nat_mult of_nat_numeral of_nat_power) |
1992 done |
1992 done |
1993 |
1993 |
1994 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint'] |
1994 lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint'] |
1995 |
1995 |
1996 lemma word_le_exists': "x \<le> y \<Longrightarrow> \<exists>z. y = x + z \<and> uint x + uint z < 2 ^ len_of TYPE('a)" |
1996 lemma word_le_exists': "x \<le> y \<Longrightarrow> \<exists>z. y = x + z \<and> uint x + uint z < 2 ^ LENGTH('a)" |
1997 for x y z :: "'a::len0 word" |
1997 for x y z :: "'a::len0 word" |
1998 apply (rule exI) |
1998 apply (rule exI) |
1999 apply (rule conjI) |
1999 apply (rule conjI) |
2000 apply (rule zadd_diff_inverse) |
2000 apply (rule zadd_diff_inverse) |
2001 apply uint_arith |
2001 apply uint_arith |
2155 |
2155 |
2156 lemma uint_and: "uint (x AND y) = uint x AND uint y" |
2156 lemma uint_and: "uint (x AND y) = uint x AND uint y" |
2157 by (transfer, simp add: bin_trunc_ao) |
2157 by (transfer, simp add: bin_trunc_ao) |
2158 |
2158 |
2159 lemma test_bit_wi [simp]: |
2159 lemma test_bit_wi [simp]: |
2160 "(word_of_int x :: 'a::len0 word) !! n \<longleftrightarrow> n < len_of TYPE('a) \<and> bin_nth x n" |
2160 "(word_of_int x :: 'a::len0 word) !! n \<longleftrightarrow> n < LENGTH('a) \<and> bin_nth x n" |
2161 by (simp add: word_test_bit_def word_ubin.eq_norm nth_bintr) |
2161 by (simp add: word_test_bit_def word_ubin.eq_norm nth_bintr) |
2162 |
2162 |
2163 lemma word_test_bit_transfer [transfer_rule]: |
2163 lemma word_test_bit_transfer [transfer_rule]: |
2164 "(rel_fun pcr_word (rel_fun (=) (=))) |
2164 "(rel_fun pcr_word (rel_fun (=) (=))) |
2165 (\<lambda>x n. n < len_of TYPE('a) \<and> bin_nth x n) (test_bit :: 'a::len0 word \<Rightarrow> _)" |
2165 (\<lambda>x n. n < LENGTH('a) \<and> bin_nth x n) (test_bit :: 'a::len0 word \<Rightarrow> _)" |
2166 unfolding rel_fun_def word.pcr_cr_eq cr_word_def by simp |
2166 unfolding rel_fun_def word.pcr_cr_eq cr_word_def by simp |
2167 |
2167 |
2168 lemma word_ops_nth_size: |
2168 lemma word_ops_nth_size: |
2169 "n < size x \<Longrightarrow> |
2169 "n < size x \<Longrightarrow> |
2170 (x OR y) !! n = (x !! n | y !! n) \<and> |
2170 (x OR y) !! n = (x !! n | y !! n) \<and> |
2180 for x :: "'a::len0 word" |
2180 for x :: "'a::len0 word" |
2181 by transfer (auto simp add: bin_nth_ops) |
2181 by transfer (auto simp add: bin_nth_ops) |
2182 |
2182 |
2183 lemma test_bit_numeral [simp]: |
2183 lemma test_bit_numeral [simp]: |
2184 "(numeral w :: 'a::len0 word) !! n \<longleftrightarrow> |
2184 "(numeral w :: 'a::len0 word) !! n \<longleftrightarrow> |
2185 n < len_of TYPE('a) \<and> bin_nth (numeral w) n" |
2185 n < LENGTH('a) \<and> bin_nth (numeral w) n" |
2186 by transfer (rule refl) |
2186 by transfer (rule refl) |
2187 |
2187 |
2188 lemma test_bit_neg_numeral [simp]: |
2188 lemma test_bit_neg_numeral [simp]: |
2189 "(- numeral w :: 'a::len0 word) !! n \<longleftrightarrow> |
2189 "(- numeral w :: 'a::len0 word) !! n \<longleftrightarrow> |
2190 n < len_of TYPE('a) \<and> bin_nth (- numeral w) n" |
2190 n < LENGTH('a) \<and> bin_nth (- numeral w) n" |
2191 by transfer (rule refl) |
2191 by transfer (rule refl) |
2192 |
2192 |
2193 lemma test_bit_1 [simp]: "(1 :: 'a::len word) !! n \<longleftrightarrow> n = 0" |
2193 lemma test_bit_1 [simp]: "(1 :: 'a::len word) !! n \<longleftrightarrow> n = 0" |
2194 by transfer auto |
2194 by transfer auto |
2195 |
2195 |
2196 lemma nth_0 [simp]: "\<not> (0 :: 'a::len0 word) !! n" |
2196 lemma nth_0 [simp]: "\<not> (0 :: 'a::len0 word) !! n" |
2197 by transfer simp |
2197 by transfer simp |
2198 |
2198 |
2199 lemma nth_minus1 [simp]: "(-1 :: 'a::len0 word) !! n \<longleftrightarrow> n < len_of TYPE('a)" |
2199 lemma nth_minus1 [simp]: "(-1 :: 'a::len0 word) !! n \<longleftrightarrow> n < LENGTH('a)" |
2200 by transfer simp |
2200 by transfer simp |
2201 |
2201 |
2202 \<comment> \<open>get from commutativity, associativity etc of \<open>int_and\<close> etc to same for \<open>word_and etc\<close>\<close> |
2202 \<comment> \<open>get from commutativity, associativity etc of \<open>int_and\<close> etc to same for \<open>word_and etc\<close>\<close> |
2203 lemmas bwsimps = |
2203 lemmas bwsimps = |
2204 wi_hom_add |
2204 wi_hom_add |
2342 by (auto simp: word_lsb_def bin_last_def) |
2342 by (auto simp: word_lsb_def bin_last_def) |
2343 |
2343 |
2344 lemma word_msb_sint: "msb w \<longleftrightarrow> sint w < 0" |
2344 lemma word_msb_sint: "msb w \<longleftrightarrow> sint w < 0" |
2345 by (simp only: word_msb_def sign_Min_lt_0) |
2345 by (simp only: word_msb_def sign_Min_lt_0) |
2346 |
2346 |
2347 lemma msb_word_of_int: "msb (word_of_int x::'a::len word) = bin_nth x (len_of TYPE('a) - 1)" |
2347 lemma msb_word_of_int: "msb (word_of_int x::'a::len word) = bin_nth x (LENGTH('a) - 1)" |
2348 by (simp add: word_msb_def word_sbin.eq_norm bin_sign_lem) |
2348 by (simp add: word_msb_def word_sbin.eq_norm bin_sign_lem) |
2349 |
2349 |
2350 lemma word_msb_numeral [simp]: |
2350 lemma word_msb_numeral [simp]: |
2351 "msb (numeral w::'a::len word) = bin_nth (numeral w) (len_of TYPE('a) - 1)" |
2351 "msb (numeral w::'a::len word) = bin_nth (numeral w) (LENGTH('a) - 1)" |
2352 unfolding word_numeral_alt by (rule msb_word_of_int) |
2352 unfolding word_numeral_alt by (rule msb_word_of_int) |
2353 |
2353 |
2354 lemma word_msb_neg_numeral [simp]: |
2354 lemma word_msb_neg_numeral [simp]: |
2355 "msb (- numeral w::'a::len word) = bin_nth (- numeral w) (len_of TYPE('a) - 1)" |
2355 "msb (- numeral w::'a::len word) = bin_nth (- numeral w) (LENGTH('a) - 1)" |
2356 unfolding word_neg_numeral_alt by (rule msb_word_of_int) |
2356 unfolding word_neg_numeral_alt by (rule msb_word_of_int) |
2357 |
2357 |
2358 lemma word_msb_0 [simp]: "\<not> msb (0::'a::len word)" |
2358 lemma word_msb_0 [simp]: "\<not> msb (0::'a::len word)" |
2359 by (simp add: word_msb_def) |
2359 by (simp add: word_msb_def) |
2360 |
2360 |
2361 lemma word_msb_1 [simp]: "msb (1::'a::len word) \<longleftrightarrow> len_of TYPE('a) = 1" |
2361 lemma word_msb_1 [simp]: "msb (1::'a::len word) \<longleftrightarrow> LENGTH('a) = 1" |
2362 unfolding word_1_wi msb_word_of_int eq_iff [where 'a=nat] |
2362 unfolding word_1_wi msb_word_of_int eq_iff [where 'a=nat] |
2363 by (simp add: Suc_le_eq) |
2363 by (simp add: Suc_le_eq) |
2364 |
2364 |
2365 lemma word_msb_nth: "msb w = bin_nth (uint w) (len_of TYPE('a) - 1)" |
2365 lemma word_msb_nth: "msb w = bin_nth (uint w) (LENGTH('a) - 1)" |
2366 for w :: "'a::len word" |
2366 for w :: "'a::len word" |
2367 by (simp add: word_msb_def sint_uint bin_sign_lem) |
2367 by (simp add: word_msb_def sint_uint bin_sign_lem) |
2368 |
2368 |
2369 lemma word_msb_alt: "msb w = hd (to_bl w)" |
2369 lemma word_msb_alt: "msb w = hd (to_bl w)" |
2370 for w :: "'a::len word" |
2370 for w :: "'a::len word" |
2532 apply (clarsimp simp add : test_bit_set_gen) |
2532 apply (clarsimp simp add : test_bit_set_gen) |
2533 apply (drule test_bit_size) |
2533 apply (drule test_bit_size) |
2534 apply force |
2534 apply force |
2535 done |
2535 done |
2536 |
2536 |
2537 lemma test_bit_2p: "(word_of_int (2 ^ n)::'a::len word) !! m \<longleftrightarrow> m = n \<and> m < len_of TYPE('a)" |
2537 lemma test_bit_2p: "(word_of_int (2 ^ n)::'a::len word) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a)" |
2538 by (auto simp: word_test_bit_def word_ubin.eq_norm nth_bintr nth_2p_bin) |
2538 by (auto simp: word_test_bit_def word_ubin.eq_norm nth_bintr nth_2p_bin) |
2539 |
2539 |
2540 lemma nth_w2p: "((2::'a::len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < len_of TYPE('a::len)" |
2540 lemma nth_w2p: "((2::'a::len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a::len)" |
2541 by (simp add: test_bit_2p [symmetric] word_of_int [symmetric]) |
2541 by (simp add: test_bit_2p [symmetric] word_of_int [symmetric]) |
2542 |
2542 |
2543 lemma uint_2p: "(0::'a::len word) < 2 ^ n \<Longrightarrow> uint (2 ^ n::'a::len word) = 2 ^ n" |
2543 lemma uint_2p: "(0::'a::len word) < 2 ^ n \<Longrightarrow> uint (2 ^ n::'a::len word) = 2 ^ n" |
2544 apply (unfold word_arith_power_alt) |
2544 apply (unfold word_arith_power_alt) |
2545 apply (case_tac "len_of TYPE('a)") |
2545 apply (case_tac "LENGTH('a)") |
2546 apply clarsimp |
2546 apply clarsimp |
2547 apply (case_tac "nat") |
2547 apply (case_tac "nat") |
2548 apply clarsimp |
2548 apply clarsimp |
2549 apply (case_tac "n") |
2549 apply (case_tac "n") |
2550 apply clarsimp |
2550 apply clarsimp |
2923 for w :: "'a::len word" |
2923 for w :: "'a::len word" |
2924 by (induct n) (auto simp: shiftl_def shiftl1_2t) |
2924 by (induct n) (auto simp: shiftl_def shiftl1_2t) |
2925 |
2925 |
2926 lemma shiftr1_bintr [simp]: |
2926 lemma shiftr1_bintr [simp]: |
2927 "(shiftr1 (numeral w) :: 'a::len0 word) = |
2927 "(shiftr1 (numeral w) :: 'a::len0 word) = |
2928 word_of_int (bin_rest (bintrunc (len_of TYPE('a)) (numeral w)))" |
2928 word_of_int (bin_rest (bintrunc (LENGTH('a)) (numeral w)))" |
2929 unfolding shiftr1_def word_numeral_alt by (simp add: word_ubin.eq_norm) |
2929 unfolding shiftr1_def word_numeral_alt by (simp add: word_ubin.eq_norm) |
2930 |
2930 |
2931 lemma sshiftr1_sbintr [simp]: |
2931 lemma sshiftr1_sbintr [simp]: |
2932 "(sshiftr1 (numeral w) :: 'a::len word) = |
2932 "(sshiftr1 (numeral w) :: 'a::len word) = |
2933 word_of_int (bin_rest (sbintrunc (len_of TYPE('a) - 1) (numeral w)))" |
2933 word_of_int (bin_rest (sbintrunc (LENGTH('a) - 1) (numeral w)))" |
2934 unfolding sshiftr1_def word_numeral_alt by (simp add: word_sbin.eq_norm) |
2934 unfolding sshiftr1_def word_numeral_alt by (simp add: word_sbin.eq_norm) |
2935 |
2935 |
2936 lemma shiftr_no [simp]: |
2936 lemma shiftr_no [simp]: |
2937 (* FIXME: neg_numeral *) |
2937 (* FIXME: neg_numeral *) |
2938 "(numeral w::'a::len0 word) >> n = word_of_int |
2938 "(numeral w::'a::len0 word) >> n = word_of_int |
2939 ((bin_rest ^^ n) (bintrunc (len_of TYPE('a)) (numeral w)))" |
2939 ((bin_rest ^^ n) (bintrunc (LENGTH('a)) (numeral w)))" |
2940 by (rule word_eqI) (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size) |
2940 by (rule word_eqI) (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size) |
2941 |
2941 |
2942 lemma sshiftr_no [simp]: |
2942 lemma sshiftr_no [simp]: |
2943 (* FIXME: neg_numeral *) |
2943 (* FIXME: neg_numeral *) |
2944 "(numeral w::'a::len word) >>> n = word_of_int |
2944 "(numeral w::'a::len word) >>> n = word_of_int |
2945 ((bin_rest ^^ n) (sbintrunc (len_of TYPE('a) - 1) (numeral w)))" |
2945 ((bin_rest ^^ n) (sbintrunc (LENGTH('a) - 1) (numeral w)))" |
2946 apply (rule word_eqI) |
2946 apply (rule word_eqI) |
2947 apply (auto simp: nth_sshiftr nth_rest_power_bin nth_sbintr word_size) |
2947 apply (auto simp: nth_sshiftr nth_rest_power_bin nth_sbintr word_size) |
2948 apply (subgoal_tac "na + n = len_of TYPE('a) - Suc 0", simp, simp)+ |
2948 apply (subgoal_tac "na + n = LENGTH('a) - Suc 0", simp, simp)+ |
2949 done |
2949 done |
2950 |
2950 |
2951 lemma shiftr1_bl_of: |
2951 lemma shiftr1_bl_of: |
2952 "length bl \<le> len_of TYPE('a) \<Longrightarrow> |
2952 "length bl \<le> LENGTH('a) \<Longrightarrow> |
2953 shiftr1 (of_bl bl::'a::len0 word) = of_bl (butlast bl)" |
2953 shiftr1 (of_bl bl::'a::len0 word) = of_bl (butlast bl)" |
2954 by (clarsimp simp: shiftr1_def of_bl_def butlast_rest_bl2bin word_ubin.eq_norm trunc_bl2bin) |
2954 by (clarsimp simp: shiftr1_def of_bl_def butlast_rest_bl2bin word_ubin.eq_norm trunc_bl2bin) |
2955 |
2955 |
2956 lemma shiftr_bl_of: |
2956 lemma shiftr_bl_of: |
2957 "length bl \<le> len_of TYPE('a) \<Longrightarrow> |
2957 "length bl \<le> LENGTH('a) \<Longrightarrow> |
2958 (of_bl bl::'a::len0 word) >> n = of_bl (take (length bl - n) bl)" |
2958 (of_bl bl::'a::len0 word) >> n = of_bl (take (length bl - n) bl)" |
2959 apply (unfold shiftr_def) |
2959 apply (unfold shiftr_def) |
2960 apply (induct n) |
2960 apply (induct n) |
2961 apply clarsimp |
2961 apply clarsimp |
2962 apply clarsimp |
2962 apply clarsimp |
2963 apply (subst shiftr1_bl_of) |
2963 apply (subst shiftr1_bl_of) |
2964 apply simp |
2964 apply simp |
2965 apply (simp add: butlast_take) |
2965 apply (simp add: butlast_take) |
2966 done |
2966 done |
2967 |
2967 |
2968 lemma shiftr_bl: "x >> n \<equiv> of_bl (take (len_of TYPE('a) - n) (to_bl x))" |
2968 lemma shiftr_bl: "x >> n \<equiv> of_bl (take (LENGTH('a) - n) (to_bl x))" |
2969 for x :: "'a::len0 word" |
2969 for x :: "'a::len0 word" |
2970 using shiftr_bl_of [where 'a='a, of "to_bl x"] by simp |
2970 using shiftr_bl_of [where 'a='a, of "to_bl x"] by simp |
2971 |
2971 |
2972 lemma msb_shift: "msb w \<longleftrightarrow> w >> (len_of TYPE('a) - 1) \<noteq> 0" |
2972 lemma msb_shift: "msb w \<longleftrightarrow> w >> (LENGTH('a) - 1) \<noteq> 0" |
2973 for w :: "'a::len word" |
2973 for w :: "'a::len word" |
2974 apply (unfold shiftr_bl word_msb_alt) |
2974 apply (unfold shiftr_bl word_msb_alt) |
2975 apply (simp add: word_size Suc_le_eq take_Suc) |
2975 apply (simp add: word_size Suc_le_eq take_Suc) |
2976 apply (cases "hd (to_bl w)") |
2976 apply (cases "hd (to_bl w)") |
2977 apply (auto simp: word_1_bl of_bl_rep_False [where n=1 and bs="[]", simplified]) |
2977 apply (auto simp: word_1_bl of_bl_rep_False [where n=1 and bs="[]", simplified]) |
3286 |
3286 |
3287 |
3287 |
3288 subsubsection \<open>Slices\<close> |
3288 subsubsection \<open>Slices\<close> |
3289 |
3289 |
3290 lemma slice1_no_bin [simp]: |
3290 lemma slice1_no_bin [simp]: |
3291 "slice1 n (numeral w :: 'b word) = of_bl (takefill False n (bin_to_bl (len_of TYPE('b::len0)) (numeral w)))" |
3291 "slice1 n (numeral w :: 'b word) = of_bl (takefill False n (bin_to_bl (LENGTH('b::len0)) (numeral w)))" |
3292 by (simp add: slice1_def) (* TODO: neg_numeral *) |
3292 by (simp add: slice1_def) (* TODO: neg_numeral *) |
3293 |
3293 |
3294 lemma slice_no_bin [simp]: |
3294 lemma slice_no_bin [simp]: |
3295 "slice n (numeral w :: 'b word) = of_bl (takefill False (len_of TYPE('b::len0) - n) |
3295 "slice n (numeral w :: 'b word) = of_bl (takefill False (LENGTH('b::len0) - n) |
3296 (bin_to_bl (len_of TYPE('b::len0)) (numeral w)))" |
3296 (bin_to_bl (LENGTH('b::len0)) (numeral w)))" |
3297 by (simp add: slice_def word_size) (* TODO: neg_numeral *) |
3297 by (simp add: slice_def word_size) (* TODO: neg_numeral *) |
3298 |
3298 |
3299 lemma slice1_0 [simp] : "slice1 n 0 = 0" |
3299 lemma slice1_0 [simp] : "slice1 n 0 = 0" |
3300 unfolding slice1_def by simp |
3300 unfolding slice1_def by simp |
3301 |
3301 |
3330 lemma slice1_up_alt': |
3330 lemma slice1_up_alt': |
3331 "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs = n + k \<Longrightarrow> |
3331 "sl = slice1 n w \<Longrightarrow> fs = size sl \<Longrightarrow> fs = n + k \<Longrightarrow> |
3332 to_bl sl = takefill False fs (replicate k False @ (to_bl w))" |
3332 to_bl sl = takefill False fs (replicate k False @ (to_bl w))" |
3333 apply (unfold slice1_def word_size of_bl_def uint_bl) |
3333 apply (unfold slice1_def word_size of_bl_def uint_bl) |
3334 apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop takefill_append [symmetric]) |
3334 apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop takefill_append [symmetric]) |
3335 apply (rule_tac f = "\<lambda>k. takefill False (len_of TYPE('a)) |
3335 apply (rule_tac f = "\<lambda>k. takefill False (LENGTH('a)) |
3336 (replicate k False @ bin_to_bl (len_of TYPE('b)) (uint w))" in arg_cong) |
3336 (replicate k False @ bin_to_bl (LENGTH('b)) (uint w))" in arg_cong) |
3337 apply arith |
3337 apply arith |
3338 done |
3338 done |
3339 |
3339 |
3340 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size] |
3340 lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size] |
3341 lemmas su1 = slice1_up_alt' [OF refl refl, unfolded word_size] |
3341 lemmas su1 = slice1_up_alt' [OF refl refl, unfolded word_size] |
3356 lemma revcast_slice1 [OF refl]: "rc = revcast w \<Longrightarrow> slice1 (size rc) w = rc" |
3356 lemma revcast_slice1 [OF refl]: "rc = revcast w \<Longrightarrow> slice1 (size rc) w = rc" |
3357 by (simp add: slice1_def revcast_def' word_size) |
3357 by (simp add: slice1_def revcast_def' word_size) |
3358 |
3358 |
3359 lemma slice1_tf_tf': |
3359 lemma slice1_tf_tf': |
3360 "to_bl (slice1 n w :: 'a::len0 word) = |
3360 "to_bl (slice1 n w :: 'a::len0 word) = |
3361 rev (takefill False (len_of TYPE('a)) (rev (takefill False n (to_bl w))))" |
3361 rev (takefill False (LENGTH('a)) (rev (takefill False n (to_bl w))))" |
3362 unfolding slice1_def by (rule word_rev_tf) |
3362 unfolding slice1_def by (rule word_rev_tf) |
3363 |
3363 |
3364 lemmas slice1_tf_tf = slice1_tf_tf' [THEN word_bl.Rep_inverse', symmetric] |
3364 lemmas slice1_tf_tf = slice1_tf_tf' [THEN word_bl.Rep_inverse', symmetric] |
3365 |
3365 |
3366 lemma rev_slice1: |
3366 lemma rev_slice1: |
3367 "n + k = len_of TYPE('a) + len_of TYPE('b) \<Longrightarrow> |
3367 "n + k = LENGTH('a) + LENGTH('b) \<Longrightarrow> |
3368 slice1 n (word_reverse w :: 'b::len0 word) = |
3368 slice1 n (word_reverse w :: 'b::len0 word) = |
3369 word_reverse (slice1 k w :: 'a::len0 word)" |
3369 word_reverse (slice1 k w :: 'a::len0 word)" |
3370 apply (unfold word_reverse_def slice1_tf_tf) |
3370 apply (unfold word_reverse_def slice1_tf_tf) |
3371 apply (rule word_bl.Rep_inverse') |
3371 apply (rule word_bl.Rep_inverse') |
3372 apply (rule rev_swap [THEN iffD1]) |
3372 apply (rule rev_swap [THEN iffD1]) |
3705 "[u,v] = p \<Longrightarrow> [su,sv] = q \<Longrightarrow> word_rsplit u = su \<Longrightarrow> |
3705 "[u,v] = p \<Longrightarrow> [su,sv] = q \<Longrightarrow> word_rsplit u = su \<Longrightarrow> |
3706 word_rsplit v = sv \<Longrightarrow> length su = length sv" |
3706 word_rsplit v = sv \<Longrightarrow> length su = length sv" |
3707 by (auto simp: word_rsplit_def bin_rsplit_len_indep) |
3707 by (auto simp: word_rsplit_def bin_rsplit_len_indep) |
3708 |
3708 |
3709 lemma length_word_rsplit_size: |
3709 lemma length_word_rsplit_size: |
3710 "n = len_of TYPE('a::len) \<Longrightarrow> |
3710 "n = LENGTH('a::len) \<Longrightarrow> |
3711 length (word_rsplit w :: 'a word list) \<le> m \<longleftrightarrow> size w \<le> m * n" |
3711 length (word_rsplit w :: 'a word list) \<le> m \<longleftrightarrow> size w \<le> m * n" |
3712 by (auto simp: word_rsplit_def word_size bin_rsplit_len_le) |
3712 by (auto simp: word_rsplit_def word_size bin_rsplit_len_le) |
3713 |
3713 |
3714 lemmas length_word_rsplit_lt_size = |
3714 lemmas length_word_rsplit_lt_size = |
3715 length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]] |
3715 length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]] |
3716 |
3716 |
3717 lemma length_word_rsplit_exp_size: |
3717 lemma length_word_rsplit_exp_size: |
3718 "n = len_of TYPE('a::len) \<Longrightarrow> |
3718 "n = LENGTH('a::len) \<Longrightarrow> |
3719 length (word_rsplit w :: 'a word list) = (size w + n - 1) div n" |
3719 length (word_rsplit w :: 'a word list) = (size w + n - 1) div n" |
3720 by (auto simp: word_rsplit_def word_size bin_rsplit_len) |
3720 by (auto simp: word_rsplit_def word_size bin_rsplit_len) |
3721 |
3721 |
3722 lemma length_word_rsplit_even_size: |
3722 lemma length_word_rsplit_even_size: |
3723 "n = len_of TYPE('a::len) \<Longrightarrow> size w = m * n \<Longrightarrow> |
3723 "n = LENGTH('a::len) \<Longrightarrow> size w = m * n \<Longrightarrow> |
3724 length (word_rsplit w :: 'a word list) = m" |
3724 length (word_rsplit w :: 'a word list) = m" |
3725 by (auto simp: length_word_rsplit_exp_size given_quot_alt) |
3725 by (auto simp: length_word_rsplit_exp_size given_quot_alt) |
3726 |
3726 |
3727 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size] |
3727 lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size] |
3728 |
3728 |
4134 |
4134 |
4135 subsection \<open>Maximum machine word\<close> |
4135 subsection \<open>Maximum machine word\<close> |
4136 |
4136 |
4137 lemma word_int_cases: |
4137 lemma word_int_cases: |
4138 fixes x :: "'a::len0 word" |
4138 fixes x :: "'a::len0 word" |
4139 obtains n where "x = word_of_int n" and "0 \<le> n" and "n < 2^len_of TYPE('a)" |
4139 obtains n where "x = word_of_int n" and "0 \<le> n" and "n < 2^LENGTH('a)" |
4140 by (cases x rule: word_uint.Abs_cases) (simp add: uints_num) |
4140 by (cases x rule: word_uint.Abs_cases) (simp add: uints_num) |
4141 |
4141 |
4142 lemma word_nat_cases [cases type: word]: |
4142 lemma word_nat_cases [cases type: word]: |
4143 fixes x :: "'a::len word" |
4143 fixes x :: "'a::len word" |
4144 obtains n where "x = of_nat n" and "n < 2^len_of TYPE('a)" |
4144 obtains n where "x = of_nat n" and "n < 2^LENGTH('a)" |
4145 by (cases x rule: word_unat.Abs_cases) (simp add: unats_def) |
4145 by (cases x rule: word_unat.Abs_cases) (simp add: unats_def) |
4146 |
4146 |
4147 lemma max_word_eq: "(max_word::'a::len word) = 2^len_of TYPE('a) - 1" |
4147 lemma max_word_eq: "(max_word::'a::len word) = 2^LENGTH('a) - 1" |
4148 by (simp add: max_word_def word_of_int_hom_syms word_of_int_2p) |
4148 by (simp add: max_word_def word_of_int_hom_syms word_of_int_2p) |
4149 |
4149 |
4150 lemma max_word_max [simp,intro!]: "n \<le> max_word" |
4150 lemma max_word_max [simp,intro!]: "n \<le> max_word" |
4151 by (cases n rule: word_int_cases) |
4151 by (cases n rule: word_int_cases) |
4152 (simp add: max_word_def word_le_def int_word_uint mod_pos_pos_trivial del: minus_mod_self1) |
4152 (simp add: max_word_def word_le_def int_word_uint mod_pos_pos_trivial del: minus_mod_self1) |
4153 |
4153 |
4154 lemma word_of_int_2p_len: "word_of_int (2 ^ len_of TYPE('a)) = (0::'a::len0 word)" |
4154 lemma word_of_int_2p_len: "word_of_int (2 ^ LENGTH('a)) = (0::'a::len0 word)" |
4155 by (subst word_uint.Abs_norm [symmetric]) simp |
4155 by (subst word_uint.Abs_norm [symmetric]) simp |
4156 |
4156 |
4157 lemma word_pow_0: "(2::'a::len word) ^ len_of TYPE('a) = 0" |
4157 lemma word_pow_0: "(2::'a::len word) ^ LENGTH('a) = 0" |
4158 proof - |
4158 proof - |
4159 have "word_of_int (2 ^ len_of TYPE('a)) = (0::'a word)" |
4159 have "word_of_int (2 ^ LENGTH('a)) = (0::'a word)" |
4160 by (rule word_of_int_2p_len) |
4160 by (rule word_of_int_2p_len) |
4161 then show ?thesis by (simp add: word_of_int_2p) |
4161 then show ?thesis by (simp add: word_of_int_2p) |
4162 qed |
4162 qed |
4163 |
4163 |
4164 lemma max_word_wrap: "x + 1 = 0 \<Longrightarrow> x = max_word" |
4164 lemma max_word_wrap: "x + 1 = 0 \<Longrightarrow> x = max_word" |