# HG changeset patch # User wenzelm # Date 1592663792 -7200 # Node ID 9d98a39aa509b7185c5e4c35b959b2c2c02b822d # Parent e18e9ac8c2051910725631b7c9ab22833a3d8a26# Parent 34be842f35310ccfe8692f536c374024a54412d1 merged diff -r 34be842f3531 -r 9d98a39aa509 src/HOL/Code_Numeral.thy --- a/src/HOL/Code_Numeral.thy Sat Jun 20 16:18:33 2020 +0200 +++ b/src/HOL/Code_Numeral.thy Sat Jun 20 16:36:32 2020 +0200 @@ -296,40 +296,34 @@ instantiation integer :: semiring_bit_shifts begin +lift_definition bit_integer :: \integer \ nat \ bool\ + is bit . + lift_definition push_bit_integer :: \nat \ integer \ integer\ - is \push_bit\ . + is push_bit . lift_definition drop_bit_integer :: \nat \ integer \ integer\ - is \drop_bit\ . + is drop_bit . + +lift_definition take_bit_integer :: \nat \ integer \ integer\ + is take_bit . instance by (standard; transfer) - (fact bit_eq_rec bits_induct push_bit_eq_mult drop_bit_eq_div + (fact bit_eq_rec bits_induct bit_iff_odd push_bit_eq_mult drop_bit_eq_div take_bit_eq_mod bits_div_0 bits_div_by_1 bits_mod_div_trivial even_succ_div_2 exp_div_exp_eq div_exp_eq mod_exp_eq mult_exp_mod_exp_eq div_exp_mod_exp_eq even_mask_div_iff even_mult_exp_div_exp_iff)+ end -context - includes lifting_syntax -begin - -lemma [transfer_rule]: - \(pcr_integer ===> (=) ===> (\)) bit bit\ - by (unfold bit_def) transfer_prover - -lemma [transfer_rule]: - \((=) ===> pcr_integer ===> pcr_integer) take_bit take_bit\ - by (unfold take_bit_eq_mod) transfer_prover - -end - instance integer :: unique_euclidean_semiring_with_bit_shifts .. lemma [code]: + \bit k n \ odd (drop_bit n k)\ \push_bit n k = k * 2 ^ n\ - \drop_bit n k = k div 2 ^ n\ for k :: integer - by (fact push_bit_eq_mult drop_bit_eq_div)+ + \drop_bit n k = k div 2 ^ n\ + \take_bit n k = k mod 2 ^ n\ for k :: integer + by (fact bit_iff_odd_drop_bit push_bit_eq_mult drop_bit_eq_div take_bit_eq_mod)+ instantiation integer :: unique_euclidean_semiring_numeral begin @@ -1027,40 +1021,34 @@ instantiation natural :: semiring_bit_shifts begin +lift_definition bit_natural :: \natural \ nat \ bool\ + is bit . + lift_definition push_bit_natural :: \nat \ natural \ natural\ - is \push_bit\ . + is push_bit . lift_definition drop_bit_natural :: \nat \ natural \ natural\ - is \drop_bit\ . + is drop_bit . + +lift_definition take_bit_natural :: \nat \ natural \ natural\ + is take_bit . instance by (standard; transfer) - (fact bit_eq_rec bits_induct push_bit_eq_mult drop_bit_eq_div + (fact bit_eq_rec bits_induct bit_iff_odd push_bit_eq_mult drop_bit_eq_div take_bit_eq_mod bits_div_0 bits_div_by_1 bits_mod_div_trivial even_succ_div_2 exp_div_exp_eq div_exp_eq mod_exp_eq mult_exp_mod_exp_eq div_exp_mod_exp_eq even_mask_div_iff even_mult_exp_div_exp_iff)+ end -context - includes lifting_syntax -begin - -lemma [transfer_rule]: - \(pcr_natural ===> (=) ===> (\)) bit bit\ - by (unfold bit_def) transfer_prover - -lemma [transfer_rule]: - \((=) ===> pcr_natural ===> pcr_natural) take_bit take_bit\ - by (unfold take_bit_eq_mod) transfer_prover - -end - instance natural :: unique_euclidean_semiring_with_bit_shifts .. lemma [code]: + \bit m n \ odd (drop_bit n m)\ \push_bit n m = m * 2 ^ n\ - \drop_bit n m = m div 2 ^ n\ for m :: natural - by (fact push_bit_eq_mult drop_bit_eq_div)+ + \drop_bit n m = m div 2 ^ n\ + \take_bit n m = m mod 2 ^ n\ for m :: natural + by (fact bit_iff_odd_drop_bit push_bit_eq_mult drop_bit_eq_div take_bit_eq_mod)+ lift_definition natural_of_integer :: "integer \ natural" is "nat :: int \ nat" diff -r 34be842f3531 -r 9d98a39aa509 src/HOL/Library/Bit_Operations.thy --- a/src/HOL/Library/Bit_Operations.thy Sat Jun 20 16:18:33 2020 +0200 +++ b/src/HOL/Library/Bit_Operations.thy Sat Jun 20 16:36:32 2020 +0200 @@ -123,7 +123,7 @@ (simp_all add: even_mask_iff even_or_iff bit_or_iff bit_mask_iff bit_exp_iff bit_double_iff not_less le_less_Suc_eq bit_1_iff, auto simp add: mult_2) qed -lemma take_bit_eq_mask [code]: +lemma take_bit_eq_mask: \take_bit n a = a AND mask n\ by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_and_iff bit_mask_iff) @@ -194,16 +194,14 @@ proof - interpret bit: boolean_algebra \(AND)\ \(OR)\ NOT 0 \- 1\ apply standard - apply (simp_all add: bit_eq_iff bit_and_iff bit_or_iff bit_not_iff) - apply (auto simp add: exp_eq_0_imp_not_bit bit_exp_iff) + apply (simp_all add: bit_eq_iff) + apply (auto simp add: bit_and_iff bit_or_iff bit_not_iff bit_exp_iff exp_eq_0_imp_not_bit) done show \boolean_algebra (AND) (OR) NOT 0 (- 1)\ by standard show \boolean_algebra.xor (AND) (OR) NOT = (XOR)\ - apply (auto simp add: fun_eq_iff bit.xor_def bit_eq_iff bit_and_iff bit_or_iff bit_not_iff bit_xor_iff) - apply (simp_all add: bit_exp_iff, simp_all add: bit_def) - apply (metis local.bit_exp_iff local.bits_div_by_0) - apply (metis local.bit_exp_iff local.bits_div_by_0) + apply (simp add: fun_eq_iff bit_eq_iff bit.xor_def) + apply (auto simp add: bit_and_iff bit_or_iff bit_not_iff bit_xor_iff exp_eq_0_imp_not_bit) done qed @@ -636,20 +634,6 @@ unbundle integer.lifting natural.lifting -context - includes lifting_syntax -begin - -lemma transfer_rule_bit_integer [transfer_rule]: - \((pcr_integer :: int \ integer \ bool) ===> (=)) bit bit\ - by (unfold bit_def) transfer_prover - -lemma transfer_rule_bit_natural [transfer_rule]: - \((pcr_natural :: nat \ natural \ bool) ===> (=)) bit bit\ - by (unfold bit_def) transfer_prover - -end - instantiation integer :: ring_bit_operations begin @@ -742,7 +726,7 @@ beyond the boundary. The property \<^prop>\(2 :: int) ^ n \ 0\ represents that \<^term>\n\ is \<^emph>\not\ beyond that boundary. - \<^item> The projection on a single bit is then @{thm bit_def [where ?'a = int, no_vars]}. + \<^item> The projection on a single bit is then @{thm bit_iff_odd [where ?'a = int, no_vars]}. \<^item> This leads to the most fundamental properties of bit values: diff -r 34be842f3531 -r 9d98a39aa509 src/HOL/Library/Z2.thy --- a/src/HOL/Library/Z2.thy Sat Jun 20 16:18:33 2020 +0200 +++ b/src/HOL/Library/Z2.thy Sat Jun 20 16:36:32 2020 +0200 @@ -194,15 +194,19 @@ end -instance bit :: semiring_bits +instantiation bit :: semiring_bits +begin + +definition bit_bit :: \bit \ nat \ bool\ + where [simp]: \bit_bit b n \ b = 1 \ n = 0\ + +instance apply standard - apply (auto simp add: power_0_left power_add) - apply (metis bit_not_1_iff of_bool_eq(2)) + apply (auto simp add: power_0_left power_add set_iff) + apply (metis bit_not_1_iff of_bool_eq(2)) done -lemma bit_bit_iff [simp]: - \bit b n \ b = 1 \ n = 0\ for b :: bit - by (cases b; cases n) (simp_all add: bit_Suc) +end instantiation bit :: semiring_bit_shifts begin @@ -213,8 +217,11 @@ definition drop_bit_bit :: \nat \ bit \ bit\ where \drop_bit n b = (if n = 0 then b else 0)\ for b :: bit +definition take_bit_bit :: \nat \ bit \ bit\ + where \take_bit n b = (if n = 0 then 0 else b)\ for b :: bit + instance - by standard (simp_all add: push_bit_bit_def drop_bit_bit_def) + by standard (simp_all add: push_bit_bit_def drop_bit_bit_def take_bit_bit_def) end diff -r 34be842f3531 -r 9d98a39aa509 src/HOL/Parity.thy --- a/src/HOL/Parity.thy Sat Jun 20 16:18:33 2020 +0200 +++ b/src/HOL/Parity.thy Sat Jun 20 16:36:32 2020 +0200 @@ -727,8 +727,16 @@ and mult_exp_mod_exp_eq: \m \ n \ (a * 2 ^ m) mod (2 ^ n) = (a mod 2 ^ (n - m)) * 2 ^ m\ and div_exp_mod_exp_eq: \a div 2 ^ n mod 2 ^ m = a mod (2 ^ (n + m)) div 2 ^ n\ and even_mult_exp_div_exp_iff: \even (a * 2 ^ m div 2 ^ n) \ m > n \ 2 ^ n = 0 \ (m \ n \ even (a div 2 ^ (n - m)))\ + fixes bit :: \'a \ nat \ bool\ + assumes bit_iff_odd: \bit a n \ odd (a div 2 ^ n)\ begin +text \ + Having \<^const>\bit\ as definitional class operation + takes into account that specific instances can be implemented + differently wrt. code generation. +\ + lemma bits_div_by_0 [simp]: \a div 0 = 0\ by (metis add_cancel_right_right bits_mod_div_trivial mod_mult_div_eq mult_not_zero) @@ -782,16 +790,13 @@ \1 mod 2 = 1\ by (simp add: mod2_eq_if) -definition bit :: \'a \ nat \ bool\ - where \bit a n \ odd (a div 2 ^ n)\ - lemma bit_0 [simp]: \bit a 0 \ odd a\ - by (simp add: bit_def) + by (simp add: bit_iff_odd) lemma bit_Suc: \bit a (Suc n) \ bit (a div 2) n\ - using div_exp_eq [of a 1 n] by (simp add: bit_def) + using div_exp_eq [of a 1 n] by (simp add: bit_iff_odd) lemma bit_rec: \bit a n \ (if n = 0 then odd a else bit (a div 2) (n - 1))\ @@ -799,7 +804,7 @@ lemma bit_0_eq [simp]: \bit 0 = bot\ - by (simp add: fun_eq_iff bit_def) + by (simp add: fun_eq_iff bit_iff_odd) context fixes a @@ -850,7 +855,7 @@ lemma exp_eq_0_imp_not_bit: \\ bit a n\ if \2 ^ n = 0\ - using that by (simp add: bit_def) + using that by (simp add: bit_iff_odd) lemma bit_eqI: \a = b\ if \\n. 2 ^ n \ 0 \ bit a n \ bit b n\ @@ -912,7 +917,7 @@ lemma bit_exp_iff: \bit (2 ^ m) n \ 2 ^ m \ 0 \ m = n\ - by (auto simp add: bit_def exp_div_exp_eq) + by (auto simp add: bit_iff_odd exp_div_exp_eq) lemma bit_1_iff: \bit 1 n \ 1 \ 0 \ n = 0\ @@ -924,7 +929,7 @@ lemma even_bit_succ_iff: \bit (1 + a) n \ bit a n \ n = 0\ if \even a\ - using that by (cases \n = 0\) (simp_all add: bit_def) + using that by (cases \n = 0\) (simp_all add: bit_iff_odd) lemma odd_bit_iff_bit_pred: \bit a n \ bit (a - 1) n \ n = 0\ if \odd a\ @@ -938,7 +943,7 @@ lemma bit_double_iff: \bit (2 * a) n \ bit a (n - 1) \ n \ 0 \ 2 ^ n \ 0\ using even_mult_exp_div_exp_iff [of a 1 n] - by (cases n, auto simp add: bit_def ac_simps) + by (cases n, auto simp add: bit_iff_odd ac_simps) lemma bit_eq_rec: \a = b \ (even a \ even b) \ a div 2 = b div 2\ (is \?P = ?Q\) @@ -970,11 +975,11 @@ lemma bit_mod_2_iff [simp]: \bit (a mod 2) n \ n = 0 \ odd a\ - by (cases a rule: parity_cases) (simp_all add: bit_def) + by (cases a rule: parity_cases) (simp_all add: bit_iff_odd) lemma bit_mask_iff: \bit (2 ^ m - 1) n \ 2 ^ n \ 0 \ n < m\ - by (simp add: bit_def even_mask_div_iff not_le) + by (simp add: bit_iff_odd even_mask_div_iff not_le) lemma bit_Numeral1_iff [simp]: \bit (numeral Num.One) n \ n = 0\ @@ -1011,7 +1016,13 @@ qed qed -instance nat :: semiring_bits +instantiation nat :: semiring_bits +begin + +definition bit_nat :: \nat \ nat \ bool\ + where \bit_nat m n \ odd (m div 2 ^ n)\ + +instance proof show \P n\ if stable: \\n. n div 2 = n \ P n\ and rec: \\n b. P n \ (of_bool b + 2 * n) div 2 = n \ P (of_bool b + 2 * n)\ @@ -1048,7 +1059,9 @@ apply (auto simp add: not_less power_add ac_simps dest!: le_Suc_ex) apply (metis (full_types) dvd_mult dvd_mult_imp_div dvd_power_iff_le not_less not_less_eq order_refl power_Suc) done -qed (auto simp add: div_mult2_eq mod_mult2_eq power_add power_diff) +qed (auto simp add: div_mult2_eq mod_mult2_eq power_add power_diff bit_nat_def) + +end lemma int_bit_induct [case_names zero minus even odd]: "P k" if zero_int: "P 0" @@ -1107,7 +1120,13 @@ qed qed -instance int :: semiring_bits +instantiation int :: semiring_bits +begin + +definition bit_int :: \int \ nat \ bool\ + where \bit_int k n \ odd (k div 2 ^ n)\ + +instance proof show \P k\ if stable: \\k. k div 2 = k \ P k\ and rec: \\k b. P k \ (of_bool b + 2 * k) div 2 = k \ P (of_bool b + 2 * k)\ @@ -1169,18 +1188,19 @@ apply (auto simp add: not_less power_add ac_simps dest!: le_Suc_ex) apply (metis Suc_leI dvd_mult dvd_mult_imp_div dvd_power_le dvd_refl power.simps(2)) done -qed (auto simp add: zdiv_zmult2_eq zmod_zmult2_eq power_add power_diff not_le) +qed (auto simp add: zdiv_zmult2_eq zmod_zmult2_eq power_add power_diff not_le bit_int_def) + +end class semiring_bit_shifts = semiring_bits + fixes push_bit :: \nat \ 'a \ 'a\ assumes push_bit_eq_mult: \push_bit n a = a * 2 ^ n\ fixes drop_bit :: \nat \ 'a \ 'a\ assumes drop_bit_eq_div: \drop_bit n a = a div 2 ^ n\ + fixes take_bit :: \nat \ 'a \ 'a\ + assumes take_bit_eq_mod: \take_bit n a = a mod 2 ^ n\ begin -definition take_bit :: \nat \ 'a \ 'a\ - where take_bit_eq_mod: \take_bit n a = a mod 2 ^ n\ - text \ Logically, \<^const>\push_bit\, \<^const>\drop_bit\ and \<^const>\take_bit\ are just aliases; having them @@ -1188,14 +1208,14 @@ would fiddle with concrete expressions \<^term>\2 ^ n\ in a way obfuscating the basic algebraic relationships between those operations. Having - \<^const>\push_bit\ and \<^const>\drop_bit\ as definitional class operations + them as definitional class operations takes into account that specific instances of these can be implemented differently wrt. code generation. \ lemma bit_iff_odd_drop_bit: \bit a n \ odd (drop_bit n a)\ - by (simp add: bit_def drop_bit_eq_div) + by (simp add: bit_iff_odd drop_bit_eq_div) lemma even_drop_bit_iff_not_bit: \even (drop_bit n a) \ \ bit a n\ @@ -1359,15 +1379,15 @@ lemma bit_push_bit_iff: \bit (push_bit m a) n \ n \ m \ 2 ^ n \ 0 \ (n < m \ bit a (n - m))\ - by (auto simp add: bit_def push_bit_eq_mult even_mult_exp_div_exp_iff) + by (auto simp add: bit_iff_odd push_bit_eq_mult even_mult_exp_div_exp_iff) lemma bit_drop_bit_eq: \bit (drop_bit n a) = bit a \ (+) n\ - by (simp add: bit_def fun_eq_iff ac_simps flip: drop_bit_eq_div) + by (simp add: bit_iff_odd fun_eq_iff ac_simps flip: drop_bit_eq_div) lemma bit_take_bit_iff: \bit (take_bit m a) n \ n < m \ bit a n\ - by (simp add: bit_def drop_bit_take_bit not_le flip: drop_bit_eq_div) + by (simp add: bit_iff_odd drop_bit_take_bit not_le flip: drop_bit_eq_div) lemma stable_imp_drop_bit_eq: \drop_bit n a = a\ @@ -1419,12 +1439,11 @@ definition drop_bit_nat :: \nat \ nat \ nat\ where \drop_bit_nat n m = m div 2 ^ n\ -instance proof - show \push_bit n m = m * 2 ^ n\ for n m :: nat - by (simp add: push_bit_nat_def) - show \drop_bit n m = m div 2 ^ n\ for n m :: nat - by (simp add: drop_bit_nat_def) -qed +definition take_bit_nat :: \nat \ nat \ nat\ + where \take_bit_nat n m = m mod 2 ^ n\ + +instance + by standard (simp_all add: push_bit_nat_def drop_bit_nat_def take_bit_nat_def) end @@ -1437,12 +1456,11 @@ definition drop_bit_int :: \nat \ int \ int\ where \drop_bit_int n k = k div 2 ^ n\ -instance proof - show \push_bit n k = k * 2 ^ n\ for n :: nat and k :: int - by (simp add: push_bit_int_def) - show \drop_bit n k = k div 2 ^ n\ for n :: nat and k :: int - by (simp add: drop_bit_int_def) -qed +definition take_bit_int :: \nat \ int \ int\ + where \take_bit_int n k = k mod 2 ^ n\ + +instance + by standard (simp_all add: push_bit_int_def drop_bit_int_def take_bit_int_def) end @@ -1538,7 +1556,7 @@ also have \of_nat (m div 2 ^ n) = of_nat m div of_nat (2 ^ n)\ by (simp add: of_nat_div) finally show ?thesis - by (simp add: bit_def semiring_bits_class.bit_def) + by (simp add: bit_iff_odd semiring_bits_class.bit_iff_odd) qed lemma of_nat_push_bit: @@ -1631,20 +1649,24 @@ by (simp add: drop_bit_eq_div minus_1_div_exp_eq_int) lemma take_bit_minus: - "take_bit n (- (take_bit n k)) = take_bit n (- k)" + \take_bit n (- take_bit n k) = take_bit n (- k)\ for k :: int by (simp add: take_bit_eq_mod mod_minus_eq) lemma take_bit_diff: - "take_bit n (take_bit n k - take_bit n l) = take_bit n (k - l)" + \take_bit n (take_bit n k - take_bit n l) = take_bit n (k - l)\ for k l :: int by (simp add: take_bit_eq_mod mod_diff_eq) lemma take_bit_nonnegative [simp]: - "take_bit n k \ 0" + \take_bit n k \ 0\ for k :: int by (simp add: take_bit_eq_mod) +lemma (in ring_1) of_nat_nat_take_bit_eq [simp]: + \of_nat (nat (take_bit n k)) = of_int (take_bit n k)\ + by simp + lemma take_bit_minus_small_eq: \take_bit n (- k) = 2 ^ n - k\ if \0 < k\ \k \ 2 ^ n\ for k :: int proof - diff -r 34be842f3531 -r 9d98a39aa509 src/HOL/Word/Word.thy --- a/src/HOL/Word/Word.thy Sat Jun 20 16:18:33 2020 +0200 +++ b/src/HOL/Word/Word.thy Sat Jun 20 16:36:32 2020 +0200 @@ -662,8 +662,29 @@ (auto simp flip: drop_bit_eq_div simp add: even_drop_bit_iff_not_bit bit_take_bit_iff, simp_all flip: push_bit_eq_mult add: bit_push_bit_iff_int) -instance word :: (len) semiring_bits +instantiation word :: (len) semiring_bits +begin + +lift_definition bit_word :: \'a word \ nat \ bool\ + is \\k n. n < LENGTH('a) \ bit k n\ proof + fix k l :: int and n :: nat + assume *: \take_bit LENGTH('a) k = take_bit LENGTH('a) l\ + show \n < LENGTH('a) \ bit k n \ n < LENGTH('a) \ bit l n\ + proof (cases \n < LENGTH('a)\) + case True + from * have \bit (take_bit LENGTH('a) k) n \ bit (take_bit LENGTH('a) l) n\ + by simp + then show ?thesis + by (simp add: bit_take_bit_iff) + next + case False + then show ?thesis + by simp + qed +qed + +instance proof show \P a\ if stable: \\a. a div 2 = a \ P a\ and rec: \\a b. P a \ (of_bool b + 2 * a) div 2 = a \ P (of_bool b + 2 * a)\ for P and a :: \'a word\ @@ -682,6 +703,8 @@ with rec [of a True] show ?case using bit_word_half_eq [of a True] by (simp add: ac_simps) qed + show \bit a n \ odd (a div 2 ^ n)\ for a :: \'a word\ and n + by transfer (simp flip: drop_bit_eq_div add: drop_bit_take_bit bit_iff_odd_drop_bit) show \0 div a = 0\ for a :: \'a word\ by transfer simp @@ -747,21 +770,6 @@ qed qed -context - includes lifting_syntax -begin - -lemma transfer_rule_bit_word [transfer_rule]: - \((pcr_word :: int \ 'a::len word \ bool) ===> (=)) (\k n. n < LENGTH('a) \ bit k n) bit\ -proof - - let ?t = \\a n. odd (take_bit LENGTH('a) a div take_bit LENGTH('a) ((2::int) ^ n))\ - have \((pcr_word :: int \ 'a word \ bool) ===> (=)) ?t bit\ - by (unfold bit_def) transfer_prover - also have \?t = (\k n. n < LENGTH('a) \ bit k n)\ - by (simp add: fun_eq_iff bit_take_bit_iff flip: bit_def) - finally show ?thesis . -qed - end instantiation word :: (len) semiring_bit_shifts @@ -788,11 +796,17 @@ is \\n. drop_bit n \ take_bit LENGTH('a)\ by (simp add: take_bit_eq_mod) +lift_definition take_bit_word :: \nat \ 'a word \ 'a word\ + is \\n. take_bit (min LENGTH('a) n)\ + by (simp add: ac_simps) (simp only: flip: take_bit_take_bit) + instance proof - show \push_bit n a = a * 2 ^ n\ for n :: nat and a :: "'a word" + show \push_bit n a = a * 2 ^ n\ for n :: nat and a :: \'a word\ by transfer (simp add: push_bit_eq_mult) - show \drop_bit n a = a div 2 ^ n\ for n :: nat and a :: "'a word" + show \drop_bit n a = a div 2 ^ n\ for n :: nat and a :: \'a word\ by transfer (simp flip: drop_bit_eq_div add: drop_bit_take_bit) + show \take_bit n a = a mod 2 ^ n\ for n :: nat and a :: \'a word\ + by transfer (auto simp flip: take_bit_eq_mod) qed end @@ -916,6 +930,10 @@ \drop_bit n w = w >> n\ for w :: \'a::len word\ by (simp add: shiftr_word_eq) +lemma [code]: + \take_bit n a = a AND Bit_Operations.mask n\ for a :: \'a::len word\ + by (fact take_bit_eq_mask) + lemma [code_abbrev]: \push_bit n 1 = (2 :: 'a::len word) ^ n\ by (fact push_bit_of_1) @@ -944,12 +962,9 @@ \even_word a \ a AND 1 = 0\ by (simp add: and_one_eq even_iff_mod_2_eq_zero even_word_def) -definition bit_word :: \'a::len word \ nat \ bool\ - where [code_abbrev]: \bit_word = bit\ - -lemma bit_word_iff [code]: - \bit_word a n \ drop_bit n a AND 1 = 1\ - by (simp add: bit_word_def bit_iff_odd_drop_bit odd_iff_mod_2_eq_one and_one_eq) +lemma bit_word_iff_drop_bit_and [code]: + \bit a n \ drop_bit n a AND 1 = 1\ for a :: \'a::len word\ + by (simp add: bit_iff_odd_drop_bit odd_iff_mod_2_eq_one and_one_eq) subsection \Shift operations\ diff -r 34be842f3531 -r 9d98a39aa509 src/HOL/ex/Word.thy --- a/src/HOL/ex/Word.thy Sat Jun 20 16:18:33 2020 +0200 +++ b/src/HOL/ex/Word.thy Sat Jun 20 16:36:32 2020 +0200 @@ -548,8 +548,29 @@ (auto simp flip: drop_bit_eq_div simp add: even_drop_bit_iff_not_bit bit_take_bit_iff, simp_all flip: push_bit_eq_mult add: bit_push_bit_iff_int) -instance word :: (len) semiring_bits +instantiation word :: (len) semiring_bits +begin + +lift_definition bit_word :: \'a word \ nat \ bool\ + is \\k n. n < LENGTH('a) \ bit k n\ proof + fix k l :: int and n :: nat + assume *: \take_bit LENGTH('a) k = take_bit LENGTH('a) l\ + show \n < LENGTH('a) \ bit k n \ n < LENGTH('a) \ bit l n\ + proof (cases \n < LENGTH('a)\) + case True + from * have \bit (take_bit LENGTH('a) k) n \ bit (take_bit LENGTH('a) l) n\ + by simp + then show ?thesis + by (simp add: bit_take_bit_iff) + next + case False + then show ?thesis + by simp + qed +qed + +instance proof show \P a\ if stable: \\a. a div 2 = a \ P a\ and rec: \\a b. P a \ (of_bool b + 2 * a) div 2 = a \ P (of_bool b + 2 * a)\ for P and a :: \'a word\ @@ -566,6 +587,8 @@ with rec [of a True] show ?case using bit_word_half_eq [of a True] by (simp add: ac_simps) qed + show \bit a n \ odd (a div 2 ^ n)\ for a :: \'a word\ and n + by transfer (simp flip: drop_bit_eq_div add: drop_bit_take_bit bit_iff_odd_drop_bit) show \0 div a = 0\ for a :: \'a word\ by transfer simp @@ -631,21 +654,6 @@ qed qed -context - includes lifting_syntax -begin - -lemma transfer_rule_bit_word [transfer_rule]: - \((pcr_word :: int \ 'a::len word \ bool) ===> (=)) (\k n. n < LENGTH('a) \ bit k n) bit\ -proof - - let ?t = \\a n. odd (take_bit LENGTH('a) a div take_bit LENGTH('a) ((2::int) ^ n))\ - have \((pcr_word :: int \ 'a word \ bool) ===> (=)) ?t bit\ - by (unfold bit_def) transfer_prover - also have \?t = (\k n. n < LENGTH('a) \ bit k n)\ - by (simp add: fun_eq_iff bit_take_bit_iff flip: bit_def) - finally show ?thesis . -qed - end instantiation word :: (len) semiring_bit_shifts @@ -672,11 +680,17 @@ is \\n. drop_bit n \ take_bit LENGTH('a)\ by (simp add: take_bit_eq_mod) +lift_definition take_bit_word :: \nat \ 'a word \ 'a word\ + is \\n. take_bit (min LENGTH('a) n)\ + by (simp add: ac_simps) (simp only: flip: take_bit_take_bit) + instance proof show \push_bit n a = a * 2 ^ n\ for n :: nat and a :: "'a word" by transfer (simp add: push_bit_eq_mult) show \drop_bit n a = a div 2 ^ n\ for n :: nat and a :: "'a word" by transfer (simp flip: drop_bit_eq_div add: drop_bit_take_bit) + show \take_bit n a = a mod 2 ^ n\ for n :: nat and a :: \'a word\ + by transfer (auto simp flip: take_bit_eq_mod) qed end @@ -723,12 +737,9 @@ \even_word a \ a AND 1 = 0\ by (simp add: even_word_def and_one_eq even_iff_mod_2_eq_zero) -definition bit_word :: \'a::len word \ nat \ bool\ - where [code_abbrev]: \bit_word = bit\ - -lemma bit_word_iff [code]: - \bit_word a n \ drop_bit n a AND 1 = 1\ - by (simp add: bit_word_def bit_iff_odd_drop_bit and_one_eq odd_iff_mod_2_eq_one) +lemma bit_word_iff_drop_bit_and [code]: + \bit a n \ drop_bit n a AND 1 = 1\ for a :: \'a::len word\ + by (simp add: bit_iff_odd_drop_bit odd_iff_mod_2_eq_one and_one_eq) lifting_update word.lifting lifting_forget word.lifting