# HG changeset patch # User haftmann # Date 1708532376 0 # Node ID c172eecba85d49b637f124fe9869d142ee948d61 # Parent 76720aeab21e86199772f58b61bd1a96b8a1db64 simplified specification of type class semiring_bits diff -r 76720aeab21e -r c172eecba85d src/HOL/Bit_Operations.thy --- a/src/HOL/Bit_Operations.thy Wed Feb 21 10:46:22 2024 +0000 +++ b/src/HOL/Bit_Operations.thy Wed Feb 21 16:19:36 2024 +0000 @@ -14,9 +14,9 @@ \(\a. a div 2 = a \ P a) \ (\a b. P a \ (of_bool b + 2 * a) div 2 = a \ P (of_bool b + 2 * a)) \ P a\ - assumes half_div_exp_eq: \a div 2 div 2 ^ n = a div 2 ^ Suc n\ + assumes bits_mod_div_trivial [simp]: \a mod b div b = 0\ + and half_div_exp_eq: \a div 2 div 2 ^ n = a div 2 ^ Suc n\ and even_double_div_exp_iff: \2 ^ Suc n \ 0 \ even (2 * a div 2 ^ Suc n) \ even (a div 2 ^ n)\ - and even_mod_exp_div_exp_iff: \even (a mod 2 ^ m div 2 ^ n) \ m \ n \ even (a div 2 ^ n)\ fixes bit :: \'a \ nat \ bool\ assumes bit_iff_odd: \bit a n \ odd (a div 2 ^ n)\ begin @@ -382,24 +382,6 @@ with rec [of n True] show ?case by simp qed - show \even (q mod 2 ^ m div 2 ^ n) \ m \ n \ even (q div 2 ^ n)\ for q m n :: nat - proof (cases \m \ n\) - case True - moreover define r where \r = n - m\ - ultimately have \n = m + r\ - by simp - with True show ?thesis - by (simp add: power_add div_mult2_eq) - next - case False - moreover define r where \r = m - Suc n\ - ultimately have \m = n + Suc r\ - by simp - moreover have \even (q mod 2 ^ (n + Suc r) div 2 ^ n) \ even (q div 2 ^ n)\ - by (simp only: power_add) (simp add: mod_mult2_eq dvd_mod_iff) - ultimately show ?thesis - by simp - qed qed (auto simp add: div_mult2_eq bit_nat_def) end @@ -539,24 +521,6 @@ with rec [of k True] show ?case by (simp add: ac_simps) qed - show \even (k mod 2 ^ m div 2 ^ n) \ m \ n \ even (k div 2 ^ n)\ for k :: int and m n :: nat - proof (cases \m \ n\) - case True - moreover define r where \r = n - m\ - ultimately have \n = m + r\ - by simp - with True show ?thesis - by (simp add: power_add zdiv_zmult2_eq) - next - case False - moreover define r where \r = m - Suc n\ - ultimately have \m = n + Suc r\ - by simp - moreover have \even (k mod 2 ^ (n + Suc r) div 2 ^ n) \ even (k div 2 ^ n)\ - by (simp only: power_add) (simp add: zmod_zmult2_eq dvd_mod_iff) - ultimately show ?thesis - by simp - qed qed (auto simp add: zdiv_zmult2_eq bit_int_def) end @@ -879,13 +843,96 @@ \push_bit (numeral l) (numeral k) = push_bit (pred_numeral l) (numeral (Num.Bit0 k))\ by (simp add: numeral_eq_Suc mult_2_right) (simp add: numeral_Bit0) +lemma bit_drop_bit_eq [bit_simps]: + \bit (drop_bit n a) = bit a \ (+) n\ + by rule (simp add: drop_bit_eq_div bit_iff_odd div_exp_eq) + +lemma disjunctive_xor_eq_or: + \a XOR b = a OR b\ if \a AND b = 0\ + using that by (auto simp add: bit_eq_iff bit_simps) + +lemma disjunctive_add_eq_or: + \a + b = a OR b\ if \a AND b = 0\ +proof (rule bit_eqI) + fix n + assume \possible_bit TYPE('a) n\ + moreover from that have \\n. \ bit (a AND b) n\ + by simp + then have \\n. \ bit a n \ \ bit b n\ + by (simp add: bit_simps) + ultimately show \bit (a + b) n \ bit (a OR b) n\ + proof (induction n arbitrary: a b) + case 0 + from "0"(2)[of 0] show ?case + by (auto simp add: even_or_iff bit_0) + next + case (Suc n) + from Suc.prems(2) [of 0] have even: \even a \ even b\ + by (auto simp add: bit_0) + have bit: \\ bit (a div 2) n \ \ bit (b div 2) n\ for n + using Suc.prems(2) [of \Suc n\] by (simp add: bit_Suc) + from Suc.prems have \possible_bit TYPE('a) n\ + using possible_bit_less_imp by force + with \\n. \ bit (a div 2) n \ \ bit (b div 2) n\ Suc.IH [of \a div 2\ \b div 2\] + have IH: \bit (a div 2 + b div 2) n \ bit (a div 2 OR b div 2) n\ + by (simp add: bit_Suc) + have \a + b = (a div 2 * 2 + a mod 2) + (b div 2 * 2 + b mod 2)\ + using div_mult_mod_eq [of a 2] div_mult_mod_eq [of b 2] by simp + also have \\ = of_bool (odd a \ odd b) + 2 * (a div 2 + b div 2)\ + using even by (auto simp add: algebra_simps mod2_eq_if) + finally have \bit ((a + b) div 2) n \ bit (a div 2 + b div 2) n\ + using \possible_bit TYPE('a) (Suc n)\ by simp (simp_all flip: bit_Suc add: bit_double_iff possible_bit_def) + also have \\ \ bit (a div 2 OR b div 2) n\ + by (rule IH) + finally show ?case + by (simp add: bit_simps flip: bit_Suc) + qed +qed + +lemma disjunctive_add_eq_xor: + \a + b = a XOR b\ if \a AND b = 0\ + using that by (simp add: disjunctive_add_eq_or disjunctive_xor_eq_or) + lemma take_bit_0 [simp]: "take_bit 0 a = 0" by (simp add: take_bit_eq_mod) lemma bit_take_bit_iff [bit_simps]: \bit (take_bit m a) n \ n < m \ bit a n\ - by (simp add: take_bit_eq_mod bit_iff_odd even_mod_exp_div_exp_iff not_le) +proof - + have \push_bit m (drop_bit m a) AND take_bit m a = 0\ (is \?lhs = _\) + proof (rule bit_eqI) + fix n + show \bit ?lhs n \ bit 0 n\ + proof (cases \m \ n\) + case False + then show ?thesis + by (simp add: bit_simps) + next + case True + moreover define q where \q = n - m\ + ultimately have \n = m + q\ by simp + moreover have \\ bit (take_bit m a) (m + q)\ + by (simp add: take_bit_eq_mod bit_iff_odd flip: div_exp_eq) + ultimately show ?thesis + by (simp add: bit_simps) + qed + qed + then have \push_bit m (drop_bit m a) XOR take_bit m a = push_bit m (drop_bit m a) + take_bit m a\ + by (simp add: disjunctive_add_eq_xor) + also have \\ = a\ + by (simp add: bits_ident) + finally have \bit (push_bit m (drop_bit m a) XOR take_bit m a) n \ bit a n\ + by simp + also have \\ \ (m \ n \ n < m) \ bit a n\ + by auto + also have \\ \ m \ n \ bit a n \ n < m \ bit a n\ + by auto + also have \m \ n \ bit a n \ bit (push_bit m (drop_bit m a)) n\ + by (auto simp add: bit_simps bit_imp_possible_bit) + finally show ?thesis + by (auto simp add: bit_simps) +qed lemma take_bit_Suc: \take_bit (Suc n) a = take_bit n (a div 2) * 2 + a mod 2\ (is \?lhs = ?rhs\) @@ -915,10 +962,6 @@ \take_bit n 1 = of_bool (n > 0)\ by (cases n) (simp_all add: take_bit_Suc) -lemma bit_drop_bit_eq [bit_simps]: - \bit (drop_bit n a) = bit a \ (+) n\ - by rule (simp add: drop_bit_eq_div bit_iff_odd div_exp_eq) - lemma drop_bit_of_0 [simp]: \drop_bit n 0 = 0\ by (rule bit_eqI) (simp add: bit_simps) @@ -1245,52 +1288,6 @@ \take_bit n a = (\k = 0.. by (simp flip: horner_sum_bit_eq_take_bit add: horner_sum_eq_sum push_bit_eq_mult) -lemma disjunctive_xor_eq_or: - \a XOR b = a OR b\ if \a AND b = 0\ - using that by (auto simp add: bit_eq_iff bit_simps) - -lemma disjunctive_add_eq_or: - \a + b = a OR b\ if \a AND b = 0\ -proof (rule bit_eqI) - fix n - assume \possible_bit TYPE('a) n\ - moreover from that have \\n. \ bit (a AND b) n\ - by simp - then have \\n. \ bit a n \ \ bit b n\ - by (simp add: bit_simps) - ultimately show \bit (a + b) n \ bit (a OR b) n\ - proof (induction n arbitrary: a b) - case 0 - from "0"(2)[of 0] show ?case - by (auto simp add: even_or_iff bit_0) - next - case (Suc n) - from Suc.prems(2) [of 0] have even: \even a \ even b\ - by (auto simp add: bit_0) - have bit: \\ bit (a div 2) n \ \ bit (b div 2) n\ for n - using Suc.prems(2) [of \Suc n\] by (simp add: bit_Suc) - from Suc.prems have \possible_bit TYPE('a) n\ - using possible_bit_less_imp by force - with \\n. \ bit (a div 2) n \ \ bit (b div 2) n\ Suc.IH [of \a div 2\ \b div 2\] - have IH: \bit (a div 2 + b div 2) n \ bit (a div 2 OR b div 2) n\ - by (simp add: bit_Suc) - have \a + b = (a div 2 * 2 + a mod 2) + (b div 2 * 2 + b mod 2)\ - using div_mult_mod_eq [of a 2] div_mult_mod_eq [of b 2] by simp - also have \\ = of_bool (odd a \ odd b) + 2 * (a div 2 + b div 2)\ - using even by (auto simp add: algebra_simps mod2_eq_if) - finally have \bit ((a + b) div 2) n \ bit (a div 2 + b div 2) n\ - using \possible_bit TYPE('a) (Suc n)\ by simp (simp_all flip: bit_Suc add: bit_double_iff possible_bit_def) - also have \\ \ bit (a div 2 OR b div 2) n\ - by (rule IH) - finally show ?case - by (simp add: bit_simps flip: bit_Suc) - qed -qed - -lemma disjunctive_add_eq_xor: - \a + b = a XOR b\ if \a AND b = 0\ - using that by (simp add: disjunctive_add_eq_or disjunctive_xor_eq_or) - lemma set_bit_eq: \set_bit n a = a + of_bool (\ bit a n) * 2 ^ n\ proof - @@ -3921,6 +3918,10 @@ \a + b = a OR b\ if \\n. \ bit a n \ \ bit b n\ by (rule disjunctive_add_eq_or) (use that in \simp add: bit_eq_iff bit_simps\) +lemma even_mod_exp_div_exp_iff [no_atp]: + \even (a mod 2 ^ m div 2 ^ n) \ m \ n \ even (a div 2 ^ n)\ + by (auto simp add: even_drop_bit_iff_not_bit bit_simps simp flip: drop_bit_eq_div take_bit_eq_mod) + end context ring_bit_operations diff -r 76720aeab21e -r c172eecba85d src/HOL/Code_Numeral.thy --- a/src/HOL/Code_Numeral.thy Wed Feb 21 10:46:22 2024 +0000 +++ b/src/HOL/Code_Numeral.thy Wed Feb 21 16:19:36 2024 +0000 @@ -349,7 +349,7 @@ instance by (standard; transfer) (fact bit_induct div_by_0 div_by_1 div_0 even_half_succ_eq - half_div_exp_eq even_double_div_exp_iff even_mod_exp_div_exp_iff + half_div_exp_eq even_double_div_exp_iff bits_mod_div_trivial bit_iff_odd push_bit_eq_mult drop_bit_eq_div take_bit_eq_mod and_rec or_rec xor_rec mask_eq_exp_minus_1 set_bit_eq_or unset_bit_eq_or_xor flip_bit_eq_xor not_eq_complement)+ @@ -1109,7 +1109,7 @@ instance by (standard; transfer) (fact bit_induct div_by_0 div_by_1 div_0 even_half_succ_eq - half_div_exp_eq even_double_div_exp_iff even_mod_exp_div_exp_iff + half_div_exp_eq even_double_div_exp_iff bits_mod_div_trivial bit_iff_odd push_bit_eq_mult drop_bit_eq_div take_bit_eq_mod and_rec or_rec xor_rec mask_eq_exp_minus_1 set_bit_eq_or unset_bit_eq_or_xor flip_bit_eq_xor not_eq_complement)+ diff -r 76720aeab21e -r c172eecba85d src/HOL/Library/Word.thy --- a/src/HOL/Library/Word.thy Wed Feb 21 10:46:22 2024 +0000 +++ b/src/HOL/Library/Word.thy Wed Feb 21 16:19:36 2024 +0000 @@ -667,6 +667,32 @@ end +lemma unat_div_distrib: + \unat (v div w) = unat v div unat w\ +proof transfer + fix k l + have \nat (take_bit LENGTH('a) k) div nat (take_bit LENGTH('a) l) \ nat (take_bit LENGTH('a) k)\ + by (rule div_le_dividend) + also have \nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\ + by (simp add: nat_less_iff) + finally show \(nat \ take_bit LENGTH('a)) (take_bit LENGTH('a) k div take_bit LENGTH('a) l) = + (nat \ take_bit LENGTH('a)) k div (nat \ take_bit LENGTH('a)) l\ + by (simp add: nat_take_bit_eq div_int_pos_iff nat_div_distrib take_bit_nat_eq_self_iff) +qed + +lemma unat_mod_distrib: + \unat (v mod w) = unat v mod unat w\ +proof transfer + fix k l + have \nat (take_bit LENGTH('a) k) mod nat (take_bit LENGTH('a) l) \ nat (take_bit LENGTH('a) k)\ + by (rule mod_less_eq_dividend) + also have \nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\ + by (simp add: nat_less_iff) + finally show \(nat \ take_bit LENGTH('a)) (take_bit LENGTH('a) k mod take_bit LENGTH('a) l) = + (nat \ take_bit LENGTH('a)) k mod (nat \ take_bit LENGTH('a)) l\ + by (simp add: nat_take_bit_eq mod_int_pos_iff less_le nat_mod_distrib take_bit_nat_eq_self_iff) +qed + instance word :: (len) semiring_parity by (standard; transfer) (auto simp add: mod_2_eq_odd take_bit_Suc elim: evenE dest: le_Suc_ex) @@ -838,6 +864,9 @@ show \0 div a = 0\ for a :: \'a word\ by transfer simp + show \a mod b div b = 0\ + for a b :: \'a word\ + by (simp add: word_eq_iff_unsigned [where ?'a = nat] unat_div_distrib unat_mod_distrib) show \a div 2 div 2 ^ n = a div 2 ^ Suc n\ for a :: \'a word\ and m n :: nat apply transfer @@ -849,10 +878,6 @@ for a :: \'a word\ and n :: nat using that by transfer (simp add: even_drop_bit_iff_not_bit bit_simps flip: drop_bit_eq_div del: power.simps) - show \even (a mod 2 ^ m div 2 ^ n) \ m \ n \ even (a div 2 ^ n)\ - for a :: \'a word\ and m n :: nat - by transfer - (auto simp flip: take_bit_eq_mod drop_bit_eq_div simp add: even_drop_bit_iff_not_bit bit_simps) qed end @@ -1301,32 +1326,6 @@ by (cases \bit w (LENGTH('a) - Suc 0)\; transfer) (simp_all add: signed_take_bit_eq signed_take_bit_def not_eq_complement mask_eq_exp_minus_1 OR_upper) -lemma unat_div_distrib: - \unat (v div w) = unat v div unat w\ -proof transfer - fix k l - have \nat (take_bit LENGTH('a) k) div nat (take_bit LENGTH('a) l) \ nat (take_bit LENGTH('a) k)\ - by (rule div_le_dividend) - also have \nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\ - by (simp add: nat_less_iff) - finally show \(nat \ take_bit LENGTH('a)) (take_bit LENGTH('a) k div take_bit LENGTH('a) l) = - (nat \ take_bit LENGTH('a)) k div (nat \ take_bit LENGTH('a)) l\ - by (simp add: nat_take_bit_eq div_int_pos_iff nat_div_distrib take_bit_nat_eq_self_iff) -qed - -lemma unat_mod_distrib: - \unat (v mod w) = unat v mod unat w\ -proof transfer - fix k l - have \nat (take_bit LENGTH('a) k) mod nat (take_bit LENGTH('a) l) \ nat (take_bit LENGTH('a) k)\ - by (rule mod_less_eq_dividend) - also have \nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\ - by (simp add: nat_less_iff) - finally show \(nat \ take_bit LENGTH('a)) (take_bit LENGTH('a) k mod take_bit LENGTH('a) l) = - (nat \ take_bit LENGTH('a)) k mod (nat \ take_bit LENGTH('a)) l\ - by (simp add: nat_take_bit_eq mod_int_pos_iff less_le nat_mod_distrib take_bit_nat_eq_self_iff) -qed - lemma uint_div_distrib: \uint (v div w) = uint v div uint w\ proof -