# HG changeset patch # User haftmann # Date 1681928490 0 # Node ID 0e054e6e7f5ee11601c1709d8329aaae33f7edc8 # Parent 2cd00c4054abca45dab94bf891f421ab547f913e clarified terminology diff -r 2cd00c4054ab -r 0e054e6e7f5e src/HOL/Examples/Gauss_Numbers.thy --- a/src/HOL/Examples/Gauss_Numbers.thy Wed Apr 19 14:48:43 2023 +0200 +++ b/src/HOL/Examples/Gauss_Numbers.thy Wed Apr 19 18:21:30 2023 +0000 @@ -4,7 +4,7 @@ section \Gauss Numbers: integral gauss numbers\ theory Gauss_Numbers - imports "HOL-Library.Rounded_Division" + imports "HOL-Library.Centered_Division" begin codatatype gauss = Gauss (Re: int) (Im: int) @@ -308,17 +308,17 @@ primcorec divide_gauss :: \gauss \ gauss \ gauss\ where - \Re (x div y) = (Re x * Re y + Im x * Im y) rdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2)\ - | \Im (x div y) = (Im x * Re y - Re x * Im y) rdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2)\ + \Re (x div y) = (Re x * Re y + Im x * Im y) cdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2)\ + | \Im (x div y) = (Im x * Re y - Re x * Im y) cdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2)\ primcorec modulo_gauss :: \gauss \ gauss \ gauss\ where \Re (x mod y) = Re x - - ((Re x * Re y + Im x * Im y) rdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Re y - - (Im x * Re y - Re x * Im y) rdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Im y)\ + ((Re x * Re y + Im x * Im y) cdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Re y - + (Im x * Re y - Re x * Im y) cdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Im y)\ | \Im (x mod y) = Im x - - ((Re x * Re y + Im x * Im y) rdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Im y + - (Im x * Re y - Re x * Im y) rdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Re y)\ + ((Re x * Re y + Im x * Im y) cdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Im y + + (Im x * Re y - Re x * Im y) cdiv ((Re y)\<^sup>2 + (Im y)\<^sup>2) * Re y)\ instance proof fix x y :: gauss @@ -334,7 +334,7 @@ \(Im y)\<^sup>2 + (Re y)\<^sup>2 = Y\ by (simp_all add: power2_eq_square algebra_simps Y_def) from \Y > 0\ show ?thesis - by (simp add: gauss_eq_iff algebra_simps) (simp add: * nonzero_mult_rdiv_cancel_right) + by (simp add: gauss_eq_iff algebra_simps) (simp add: * nonzero_mult_cdiv_cancel_right) qed show \x div y * y + x mod y = x\ by (simp add: gauss_eq_iff) @@ -360,22 +360,22 @@ by (simp_all add: gauss_neq_0 euclidean_size_gauss_def) have \X * Y = R\<^sup>2 + I\<^sup>2\ by (simp add: R_def I_def X_def Y_def power2_eq_square algebra_simps) - let ?lhs = \X - I * (I rdiv Y) - R * (R rdiv Y) - - I rdiv Y * (I rmod Y) - R rdiv Y * (R rmod Y)\ - have \?lhs = X + Y * (R rdiv Y) * (R rdiv Y) + Y * (I rdiv Y) * (I rdiv Y) - - 2 * (R rdiv Y * R + I rdiv Y * I)\ - by (simp flip: minus_rmod_eq_mult_rdiv add: algebra_simps) + let ?lhs = \X - I * (I cdiv Y) - R * (R cdiv Y) + - I cdiv Y * (I cmod Y) - R cdiv Y * (R cmod Y)\ + have \?lhs = X + Y * (R cdiv Y) * (R cdiv Y) + Y * (I cdiv Y) * (I cdiv Y) + - 2 * (R cdiv Y * R + I cdiv Y * I)\ + by (simp flip: minus_cmod_eq_mult_cdiv add: algebra_simps) also have \\ = (Re (x mod y))\<^sup>2 + (Im (x mod y))\<^sup>2\ by (simp add: X_def Y_def R_def I_def algebra_simps power2_eq_square) finally have lhs: \int (euclidean_size (x mod y)) = ?lhs\ by (simp add: euclidean_size_gauss_def) - have \?lhs * Y = (I rmod Y)\<^sup>2 + (R rmod Y)\<^sup>2\ + have \?lhs * Y = (I cmod Y)\<^sup>2 + (R cmod Y)\<^sup>2\ apply (simp add: algebra_simps power2_eq_square \X * Y = R\<^sup>2 + I\<^sup>2\) - apply (simp flip: mult.assoc add.assoc minus_rmod_eq_mult_rdiv) + apply (simp flip: mult.assoc add.assoc minus_cmod_eq_mult_cdiv) apply (simp add: algebra_simps) done also have \\ \ (Y div 2)\<^sup>2 + (Y div 2)\<^sup>2\ - by (rule add_mono) (use \Y > 0\ abs_rmod_less_equal [of Y] in \simp_all add: power2_le_iff_abs_le\) + by (rule add_mono) (use \Y > 0\ abs_cmod_less_equal [of Y] in \simp_all add: power2_le_iff_abs_le\) also have \\ < Y\<^sup>2\ using \Y > 0\ by (cases \Y = 1\) (simp_all add: power2_eq_square mult_le_less_imp_less flip: mult.assoc) finally have \?lhs * Y < Y\<^sup>2\ . diff -r 2cd00c4054ab -r 0e054e6e7f5e src/HOL/Library/Centered_Division.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Library/Centered_Division.thy Wed Apr 19 18:21:30 2023 +0000 @@ -0,0 +1,178 @@ +(* Author: Florian Haftmann, TU Muenchen +*) + +section \Division with modulus centered towards zero.\ + +theory Centered_Division + imports Main +begin + +lemma off_iff_abs_mod_2_eq_one: + \odd l \ \l\ mod 2 = 1\ for l :: int + by (simp flip: odd_iff_mod_2_eq_one) + +text \ + \noindent The following specification of division on integers centers + the modulus around zero. This is useful e.g.~to define division + on Gauss numbers. + N.b.: This is not mentioned \cite{leijen01}. +\ + +definition centered_divide :: \int \ int \ int\ (infixl \cdiv\ 70) + where \k cdiv l = sgn l * ((k + \l\ div 2) div \l\)\ + +definition centered_modulo :: \int \ int \ int\ (infixl \cmod\ 70) + where \k cmod l = (k + \l\ div 2) mod \l\ - \l\ div 2\ + +text \ + \noindent Example: @{lemma \k cmod 5 \ {-2, -1, 0, 1, 2}\ by (auto simp add: centered_modulo_def)} +\ + +lemma signed_take_bit_eq_cmod: + \signed_take_bit n k = k cmod (2 ^ Suc n)\ + by (simp only: centered_modulo_def power_abs abs_numeral flip: take_bit_eq_mod) + (simp add: signed_take_bit_eq_take_bit_shift) + +text \ + \noindent Property @{thm signed_take_bit_eq_cmod [no_vars]} is the key to generalize + centered division to arbitrary structures satisfying \<^class>\ring_bit_operations\, + but so far it is not clear what practical relevance that would have. +\ + +lemma cdiv_mult_cmod_eq: + \k cdiv l * l + k cmod l = k\ +proof - + have *: \l * (sgn l * j) = \l\ * j\ for j + by (simp add: ac_simps abs_sgn) + show ?thesis + by (simp add: centered_divide_def centered_modulo_def algebra_simps *) +qed + +lemma mult_cdiv_cmod_eq: + \l * (k cdiv l) + k cmod l = k\ + using cdiv_mult_cmod_eq [of k l] by (simp add: ac_simps) + +lemma cmod_cdiv_mult_eq: + \k cmod l + k cdiv l * l = k\ + using cdiv_mult_cmod_eq [of k l] by (simp add: ac_simps) + +lemma cmod_mult_cdiv_eq: + \k cmod l + l * (k cdiv l) = k\ + using cdiv_mult_cmod_eq [of k l] by (simp add: ac_simps) + +lemma minus_cdiv_mult_eq_cmod: + \k - k cdiv l * l = k cmod l\ + by (rule add_implies_diff [symmetric]) (fact cmod_cdiv_mult_eq) + +lemma minus_mult_cdiv_eq_cmod: + \k - l * (k cdiv l) = k cmod l\ + by (rule add_implies_diff [symmetric]) (fact cmod_mult_cdiv_eq) + +lemma minus_cmod_eq_cdiv_mult: + \k - k cmod l = k cdiv l * l\ + by (rule add_implies_diff [symmetric]) (fact cdiv_mult_cmod_eq) + +lemma minus_cmod_eq_mult_cdiv: + \k - k cmod l = l * (k cdiv l)\ + by (rule add_implies_diff [symmetric]) (fact mult_cdiv_cmod_eq) + +lemma cdiv_0_eq [simp]: + \k cdiv 0 = 0\ + by (simp add: centered_divide_def) + +lemma cmod_0_eq [simp]: + \k cmod 0 = k\ + by (simp add: centered_modulo_def) + +lemma cdiv_1_eq [simp]: + \k cdiv 1 = k\ + by (simp add: centered_divide_def) + +lemma cmod_1_eq [simp]: + \k cmod 1 = 0\ + by (simp add: centered_modulo_def) + +lemma zero_cdiv_eq [simp]: + \0 cdiv k = 0\ + by (auto simp add: centered_divide_def not_less zdiv_eq_0_iff) + +lemma zero_cmod_eq [simp]: + \0 cmod k = 0\ + by (auto simp add: centered_modulo_def not_less zmod_trivial_iff) + +lemma cdiv_minus_eq: + \k cdiv - l = - (k cdiv l)\ + by (simp add: centered_divide_def) + +lemma cmod_minus_eq [simp]: + \k cmod - l = k cmod l\ + by (simp add: centered_modulo_def) + +lemma cdiv_abs_eq: + \k cdiv \l\ = sgn l * (k cdiv l)\ + by (simp add: centered_divide_def) + +lemma cmod_abs_eq [simp]: + \k cmod \l\ = k cmod l\ + by (simp add: centered_modulo_def) + +lemma nonzero_mult_cdiv_cancel_right: + \k * l cdiv l = k\ if \l \ 0\ +proof - + have \sgn l * k * \l\ cdiv l = k\ + using that by (simp add: centered_divide_def) + with that show ?thesis + by (simp add: ac_simps abs_sgn) +qed + +lemma cdiv_self_eq [simp]: + \k cdiv k = 1\ if \k \ 0\ + using that nonzero_mult_cdiv_cancel_right [of k 1] by simp + +lemma cmod_self_eq [simp]: + \k cmod k = 0\ +proof - + have \(sgn k * \k\ + \k\ div 2) mod \k\ = \k\ div 2\ + by (auto simp add: zmod_trivial_iff) + also have \sgn k * \k\ = k\ + by (simp add: abs_sgn) + finally show ?thesis + by (simp add: centered_modulo_def algebra_simps) +qed + +lemma cmod_less_divisor: + \k cmod l < \l\ - \l\ div 2\ if \l \ 0\ + using that pos_mod_bound [of \\l\\] by (simp add: centered_modulo_def) + +lemma cmod_less_equal_divisor: + \k cmod l \ \l\ div 2\ if \l \ 0\ +proof - + from that cmod_less_divisor [of l k] + have \k cmod l < \l\ - \l\ div 2\ + by simp + also have \\l\ - \l\ div 2 = \l\ div 2 + of_bool (odd l)\ + by auto + finally show ?thesis + by (cases \even l\) simp_all +qed + +lemma divisor_less_equal_cmod': + \\l\ div 2 - \l\ \ k cmod l\ if \l \ 0\ +proof - + have \0 \ (k + \l\ div 2) mod \l\\ + using that pos_mod_sign [of \\l\\] by simp + then show ?thesis + by (simp_all add: centered_modulo_def) +qed + +lemma divisor_less_equal_cmod: + \- (\l\ div 2) \ k cmod l\ if \l \ 0\ + using that divisor_less_equal_cmod' [of l k] + by (simp add: centered_modulo_def) + +lemma abs_cmod_less_equal: + \\k cmod l\ \ \l\ div 2\ if \l \ 0\ + using that divisor_less_equal_cmod [of l k] + by (simp add: abs_le_iff cmod_less_equal_divisor) + +end diff -r 2cd00c4054ab -r 0e054e6e7f5e src/HOL/Library/Library.thy --- a/src/HOL/Library/Library.thy Wed Apr 19 14:48:43 2023 +0200 +++ b/src/HOL/Library/Library.thy Wed Apr 19 18:21:30 2023 +0000 @@ -6,6 +6,7 @@ BNF_Axiomatization BNF_Corec Bourbaki_Witt_Fixpoint + Centered_Division Char_ord Code_Cardinality Code_Lazy @@ -78,7 +79,6 @@ Ramsey Reflection Rewrite - Rounded_Division Saturated Set_Algebras Set_Idioms diff -r 2cd00c4054ab -r 0e054e6e7f5e src/HOL/Library/Rounded_Division.thy --- a/src/HOL/Library/Rounded_Division.thy Wed Apr 19 14:48:43 2023 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -(* Author: Florian Haftmann, TU Muenchen -*) - -section \Rounded division: modulus centered towards zero.\ - -theory Rounded_Division - imports Main -begin - -lemma off_iff_abs_mod_2_eq_one: - \odd l \ \l\ mod 2 = 1\ for l :: int - by (simp flip: odd_iff_mod_2_eq_one) - -text \ - \noindent The following specification of division on integers centers - the modulus around zero. This is useful e.g.~to define division - on Gauss numbers. - N.b.: This is not mentioned \cite{leijen01}. -\ - -definition rounded_divide :: \int \ int \ int\ (infixl \rdiv\ 70) - where \k rdiv l = sgn l * ((k + \l\ div 2) div \l\)\ - -definition rounded_modulo :: \int \ int \ int\ (infixl \rmod\ 70) - where \k rmod l = (k + \l\ div 2) mod \l\ - \l\ div 2\ - -text \ - \noindent Example: @{lemma \k rmod 5 \ {-2, -1, 0, 1, 2}\ by (auto simp add: rounded_modulo_def)} -\ - -lemma signed_take_bit_eq_rmod: - \signed_take_bit n k = k rmod (2 ^ Suc n)\ - by (simp only: rounded_modulo_def power_abs abs_numeral flip: take_bit_eq_mod) - (simp add: signed_take_bit_eq_take_bit_shift) - -text \ - \noindent Property @{thm signed_take_bit_eq_rmod [no_vars]} is the key to generalize - rounded division to arbitrary structures satisfying \<^class>\ring_bit_operations\, - but so far it is not clear what practical relevance that would have. -\ - -lemma rdiv_mult_rmod_eq: - \k rdiv l * l + k rmod l = k\ -proof - - have *: \l * (sgn l * j) = \l\ * j\ for j - by (simp add: ac_simps abs_sgn) - show ?thesis - by (simp add: rounded_divide_def rounded_modulo_def algebra_simps *) -qed - -lemma mult_rdiv_rmod_eq: - \l * (k rdiv l) + k rmod l = k\ - using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps) - -lemma rmod_rdiv_mult_eq: - \k rmod l + k rdiv l * l = k\ - using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps) - -lemma rmod_mult_rdiv_eq: - \k rmod l + l * (k rdiv l) = k\ - using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps) - -lemma minus_rdiv_mult_eq_rmod: - \k - k rdiv l * l = k rmod l\ - by (rule add_implies_diff [symmetric]) (fact rmod_rdiv_mult_eq) - -lemma minus_mult_rdiv_eq_rmod: - \k - l * (k rdiv l) = k rmod l\ - by (rule add_implies_diff [symmetric]) (fact rmod_mult_rdiv_eq) - -lemma minus_rmod_eq_rdiv_mult: - \k - k rmod l = k rdiv l * l\ - by (rule add_implies_diff [symmetric]) (fact rdiv_mult_rmod_eq) - -lemma minus_rmod_eq_mult_rdiv: - \k - k rmod l = l * (k rdiv l)\ - by (rule add_implies_diff [symmetric]) (fact mult_rdiv_rmod_eq) - -lemma rdiv_0_eq [simp]: - \k rdiv 0 = 0\ - by (simp add: rounded_divide_def) - -lemma rmod_0_eq [simp]: - \k rmod 0 = k\ - by (simp add: rounded_modulo_def) - -lemma rdiv_1_eq [simp]: - \k rdiv 1 = k\ - by (simp add: rounded_divide_def) - -lemma rmod_1_eq [simp]: - \k rmod 1 = 0\ - by (simp add: rounded_modulo_def) - -lemma zero_rdiv_eq [simp]: - \0 rdiv k = 0\ - by (auto simp add: rounded_divide_def not_less zdiv_eq_0_iff) - -lemma zero_rmod_eq [simp]: - \0 rmod k = 0\ - by (auto simp add: rounded_modulo_def not_less zmod_trivial_iff) - -lemma rdiv_minus_eq: - \k rdiv - l = - (k rdiv l)\ - by (simp add: rounded_divide_def) - -lemma rmod_minus_eq [simp]: - \k rmod - l = k rmod l\ - by (simp add: rounded_modulo_def) - -lemma rdiv_abs_eq: - \k rdiv \l\ = sgn l * (k rdiv l)\ - by (simp add: rounded_divide_def) - -lemma rmod_abs_eq [simp]: - \k rmod \l\ = k rmod l\ - by (simp add: rounded_modulo_def) - -lemma nonzero_mult_rdiv_cancel_right: - \k * l rdiv l = k\ if \l \ 0\ -proof - - have \sgn l * k * \l\ rdiv l = k\ - using that by (simp add: rounded_divide_def) - with that show ?thesis - by (simp add: ac_simps abs_sgn) -qed - -lemma rdiv_self_eq [simp]: - \k rdiv k = 1\ if \k \ 0\ - using that nonzero_mult_rdiv_cancel_right [of k 1] by simp - -lemma rmod_self_eq [simp]: - \k rmod k = 0\ -proof - - have \(sgn k * \k\ + \k\ div 2) mod \k\ = \k\ div 2\ - by (auto simp add: zmod_trivial_iff) - also have \sgn k * \k\ = k\ - by (simp add: abs_sgn) - finally show ?thesis - by (simp add: rounded_modulo_def algebra_simps) -qed - -lemma rmod_less_divisor: - \k rmod l < \l\ - \l\ div 2\ if \l \ 0\ - using that pos_mod_bound [of \\l\\] by (simp add: rounded_modulo_def) - -lemma rmod_less_equal_divisor: - \k rmod l \ \l\ div 2\ if \l \ 0\ -proof - - from that rmod_less_divisor [of l k] - have \k rmod l < \l\ - \l\ div 2\ - by simp - also have \\l\ - \l\ div 2 = \l\ div 2 + of_bool (odd l)\ - by auto - finally show ?thesis - by (cases \even l\) simp_all -qed - -lemma divisor_less_equal_rmod': - \\l\ div 2 - \l\ \ k rmod l\ if \l \ 0\ -proof - - have \0 \ (k + \l\ div 2) mod \l\\ - using that pos_mod_sign [of \\l\\] by simp - then show ?thesis - by (simp_all add: rounded_modulo_def) -qed - -lemma divisor_less_equal_rmod: - \- (\l\ div 2) \ k rmod l\ if \l \ 0\ - using that divisor_less_equal_rmod' [of l k] - by (simp add: rounded_modulo_def) - -lemma abs_rmod_less_equal: - \\k rmod l\ \ \l\ div 2\ if \l \ 0\ - using that divisor_less_equal_rmod [of l k] - by (simp add: abs_le_iff rmod_less_equal_divisor) - -end diff -r 2cd00c4054ab -r 0e054e6e7f5e src/HOL/ex/Note_on_signed_division_on_words.thy --- a/src/HOL/ex/Note_on_signed_division_on_words.thy Wed Apr 19 14:48:43 2023 +0200 +++ b/src/HOL/ex/Note_on_signed_division_on_words.thy Wed Apr 19 18:21:30 2023 +0000 @@ -1,5 +1,5 @@ theory Note_on_signed_division_on_words - imports "HOL-Library.Word" "HOL-Library.Rounded_Division" + imports "HOL-Library.Word" "HOL-Library.Centered_Division" begin unbundle bit_operations_syntax @@ -24,26 +24,26 @@ end lift_definition signed_divide_word :: \'a::len word \ 'a word \ 'a word\ (infixl \wdiv\ 70) - is \\a b. signed_take_bit (LENGTH('a) - Suc 0) a rdiv signed_take_bit (LENGTH('a) - Suc 0) b\ + is \\a b. signed_take_bit (LENGTH('a) - Suc 0) a cdiv signed_take_bit (LENGTH('a) - Suc 0) b\ by (simp flip: signed_take_bit_decr_length_iff) lift_definition signed_modulo_word :: \'a::len word \ 'a word \ 'a word\ (infixl \wmod\ 70) - is \\a b. signed_take_bit (LENGTH('a) - Suc 0) a rmod signed_take_bit (LENGTH('a) - Suc 0) b\ + is \\a b. signed_take_bit (LENGTH('a) - Suc 0) a cmod signed_take_bit (LENGTH('a) - Suc 0) b\ by (simp flip: signed_take_bit_decr_length_iff) lemma signed_take_bit_eq_wmod: \signed_take_bit n w = w wmod (2 ^ Suc n)\ proof (transfer fixing: n) show \take_bit LENGTH('a) (signed_take_bit n (take_bit LENGTH('a) k)) = - take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - Suc 0) k rmod signed_take_bit (LENGTH('a) - Suc 0) (2 ^ Suc n))\ for k :: int + take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - Suc 0) k cmod signed_take_bit (LENGTH('a) - Suc 0) (2 ^ Suc n))\ for k :: int proof (cases \LENGTH('a) = Suc (Suc n)\) case True then show ?thesis - by (simp add: signed_take_bit_exp_eq_int signed_take_bit_take_bit rmod_minus_eq flip: power_Suc signed_take_bit_eq_rmod) + by (simp add: signed_take_bit_exp_eq_int signed_take_bit_take_bit cmod_minus_eq flip: power_Suc signed_take_bit_eq_cmod) next case False then show ?thesis - by (auto simp add: signed_take_bit_exp_eq_int signed_take_bit_take_bit take_bit_signed_take_bit simp flip: power_Suc signed_take_bit_eq_rmod) + by (auto simp add: signed_take_bit_exp_eq_int signed_take_bit_take_bit take_bit_signed_take_bit simp flip: power_Suc signed_take_bit_eq_cmod) qed qed